2017-06-30 11 views
2

私は、相対レイアウト内に2つのTextViewを含むアンドロイドでカスタム複合ビューを作成しています。 2つのクラスがあります.1つは、複合ビューであるBarcodeScannerViewと、カスタムビューを使用する別のアクティビティです。コードは以下の通りです。Androidカスタムビューイベントリスナーが静的参照なしで正常に動作しない

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); 
} 

} 

私はそれがヌル点の例外を与えるBarcodeScannerViewクラスののonClick()メソッドを呼び出したときに問題があります。

java.lang.NullPointerExceptionが:私は場合onClickScannerBox(気づいヌルオブジェクト参照デバッグにおいて

のインターフェイスメソッドを呼び出す試み 'ボイド[パッケージ名] $ ScannerListener.onClickScannerBox()')が呼び出されると、スキャナオブジェクトが初期化されます。しかし、BarcodeScannerViewでonClickScannerBox()を実行すると、scannerオブジェクトはnullになります。

私の所見によると、onClickScannerBox()が呼び出されたとき、BarcodeScannerViewオブジェクトインスタンスが初期化され、onClickScannerBox()が終了し、別のBarcodeScannerViewオブジェクトインスタンスのonClick()メソッド内にあるので、スキャナオブジェクトはnullになります。

この問題は、静的スキャナオブジェクトを使用して簡単に修正できます。 (このコードはあまりにも長くなるのでここでは提供されていません)静的な参照を持つことはこの問題の最善のアプローチだとは思いません。静的参照を使用せずに問題を修正する方法はありますか?どんな提案も感謝しています。

答えて

0

カスタムコンパウンドビューのインスタンスが2つあります.1つはレイアウト(アクティビティレイアウト)にあり、もう1つはアクティビティonCreateメソッドに明示的に作成されています。

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

あなたは、単に彼らは2つのインスタンスが、レイアウトで使用するビューについての手掛かりを持っていない、明示的に作成したものにリスナーを設定しています。次のようにxmlで作成されたインスタンスを使用する必要があります。

@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アクティビティのレイアウトで使用される化合物のビューに指定されているIDでなければなりません。

関連する問題