2017-06-30 5 views
2

Ich erstelle eine benutzerdefinierte zusammengesetzte Ansicht in Android, die zwei TextViews in einem relativen Layout enthält. Es gibt zwei Klassen, eine ist BarcodeScannerView, die die zusammengesetzte Ansicht darstellt, und eine andere Aktivität, die die benutzerdefinierte Ansicht verwendet. Der Code ist wie folgt.Android benutzerdefinierte Ansicht Ereignislistener funktioniert nicht ordnungsgemäß ohne statische Referenz

BarcodeScannerView.java

public class BarcodeScannerView extends RelativeLayout implements View.OnClickListener { 

    private int boxRadius; 
    private String boxText; 
    private int boxColor, boxEntityColor; 
    private TextView entityName; 
    private TextView manualEntry; 
    private ImageView scannerReadyImv; 
    private RelativeLayout scannerBox; 
    private OnClickListener listener; 
    private ScannerListener scanner; 
    private ScannerState state; 
    // private static BarcodeScannerView instance; 

    public enum ScannerState { 
     IDLE, READY, COMPLETE; 
    } 

    public interface ScannerListener { 

     void onClickScannerBox(); 
     void scannerIdle(); 
    } 

    public BarcodeScannerView(Context context) { 
     super(context); 
    } 

    public BarcodeScannerView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context, attrs); 
    } 

    private void init(Context context, AttributeSet attrs) { 

     View.inflate(context, R.layout.activity_barcode_scanner, this); 
     setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS); 

     entityName = (TextView) findViewById(R.id.entityNameTV); 
     manualEntry = (TextView) findViewById(R.id.manualEntryTV); 
     scannerReadyImv = (ImageView) findViewById(R.id.scannerReadyImv); 
     scannerBox = (RelativeLayout) findViewById(R.id.scannerBox); 

     manualEntry.setOnClickListener(this); 
     scannerBox.setOnClickListener(this); 

     // Assign custom attributes 
     TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.barcodeviewer, 0, 0); 

     try { 

      boxEntityColor = a.getInteger(R.styleable.barcodeviewer_boxEntityColor, 0); 
      setBoxEntityColor(boxEntityColor); 

     } finally { 
      a.recycle(); 
     } 

    } 

    // Set custom attributes 
    private void setBoxEntityColor(int color) { 
     this.entityName.setTextColor(color); 
    } 

    // Set event handlers 
    public void setOnClickListener(OnClickListener listener) { 
     this.listener = listener; 
    } 

    public void setOnScannerListener(ScannerListener scanner) { 
     this.scanner = scanner; 
    } 


    // Setters and getters 
    public void setScannerState(ScannerState state) { 
     this.state = state; 
    } 

    public ScannerState getScannerState() { 
     return this.state; 
    } 

    private void setScannerReadyState() { 
     scannerBox.setBackgroundResource(R.drawable.bc_active_4); 
     scannerReadyImv.setVisibility(View.VISIBLE); 
    } 

    public void onClick(View v) { 

     if (v.getId() == R.id.scannerBox) { 
      this.scanner.onClickScannerBox(); 
      if (this.getScannerState() == ScannerState.IDLE) { 
       setScannerReadyState(); 
      } 
     } 
    } 
} 

MainActivity.java

public class MainActivity extends AppCompatActivity implements BarcodeScannerView.ScannerListener { 

private BarcodeScannerView barcodeScannerView; 

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main_activity); 
    /*barcodeScannerView = BarcodeScannerView.instance(MainActivity.this); 
    barcodeScannerView.setOnScannerListener(this);*/ 
    barcodeScannerView = new BarcodeScannerView(this); 
    barcodeScannerView.setOnScannerListener(this); 
} 

@Override 
public void onClickScannerBox() { 
    scannerIdle(); 
} 

@Override 
public void scannerIdle(){ 
    barcodeScannerView.setScannerState(BarcodeScannerView.ScannerState.IDLE); 
} 

} 

Das Problem ist, wenn ich die onClick() -Methode der BarcodeScannerView Klasse nennen es einen Nullpunkt Ausnahme gibt.

java.lang.NullPointerException: Versuch Interface-Methode 'void [Paket] $ ScannerListener.onClickScannerBox()' auf einer Null-Objekt Referenz

In Debuggen aufzurufen bemerkte ich, dass, wenn die onClickScannerBox() aufgerufen wird, wird das Scanner-Objekt initialisiert. Aber nachdem onClickScannerBox() in BarcodeScannerView ausgeführt wurde, wird das Scanner-Objekt null.

Nach meiner Beobachtung ist der Grund, wenn onClickScannerBox() eine Instanz BarcodeScannerView Objekts aufgerufen wird, initialisiert und wenn die onClickScannerBox() beendet und aus dem Verfahren kommt, da es in der onClick() -Methode einer anderen BarcodeScannerView Objektinstanz Das Scannerobjekt wird null.

Ich kann dieses Problem einfach mit statischen Scannerobjekt beheben. (Der Code ist hier nicht vorgesehen, da das zu lange dauert) Ich glaube nicht, statische Referenzen zu haben, ist der beste Ansatz für dieses Problem. Gibt es einen Ansatz, das Problem zu beheben, ohne statische Referenzen zu verwenden? Irgendwelche Vorschläge werden geschätzt.

Antwort

0

In Ihrer Implementierung kommen zwei Instanzen Ihrer benutzerdefinierten zusammengesetzten Ansicht ins Spiel, eine ist im Layout (Aktivitätslayout) und eine andere wird explizit in der Aktivität onCreate Methode erstellt.

barcodeScannerView = new BarcodeScannerView(this); 
barcodeScannerView.setOnScannerListener(this); 

Sie haben den Hörer auf die explizit erstellt eins gesetzt, die nicht Anhaltspunkt über Ansicht im Layout verwendet hat, einfach sind sie zwei Instanzen. Sie sollten die erstellte Instanz (aufgeblasen) wie folgt in der XML-Datei verwenden.

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main_activity); 

    barcodeScannerView = (BarcodeScannerView) findViewById(R.id.barcode_scanner); 
    barcodeScannerView.setOnScannerListener(this); 
} 

barcode_scanner sollte die ID, die Sie zu der Verbindung Ansicht in der Aktivität Layout verwendet gegeben haben.

Verwandte Themen