0

メニュー項目からダイアログを呼び出しており、そのダイアログ内にボタンがあり、ボタンを押すと何かをしようとしています。このための私のコードの一部は次のとおりです。

    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.itTip:
        final Dialog tipCalculator = new Dialog(this);
        tipCalculator.setTitle("Tip Calculator");
        tipCalculator.setContentView(R.layout.tip_layout);

        totalBill = (EditText) findViewById(R.id.editTBill);
        tips = (EditText) findViewById(R.id.editTTip);
        calculate = (Button) findViewById(R.id.bCalcTip);
        tvResult = (TextView) findViewById(R.id.tvTipResult);

        calculate.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "Calculate clicked", Toast.LENGTH_SHORT).show();
            }
        });

        tipCalculator.setCancelable(true);
        tipCalculator.show();
        break;

    }
    return super.onOptionsItemSelected(item);
}

setOnClickListener を使用せずにアプリを実行すると、正常に動作し、ダイアログが完全に表示されます。しかし、リスナーを使用しようとすると、クラッシュします。LogCat をチェックインしましたが、実際には問題を明確に理解できませんでした。ここで誰かが私を助けてくれることを願っています。

4

1 に答える 1

0

問題は、実際にビューを表示する前にビューを見つけようとするためだと思います。これにより、onClickListener を割り当てようとすると「計算」が null になり、null ポインター例外がスローされます。

もう少し詳しく説明すると、findViewById は現在表示されているすべてのビューを検索し、その ID に一致するビューを返します。ボタンは R.layout.tip_layout に含まれていますが、そのビューは tipCalculator.show() が呼び出されるまで膨張せず、検索されたビューのリストに含まれないため、findViewById は null を返します。

これを機能させるにはいくつかの方法がありますが、元のコードを変更する必要が最も少ないのは次の方法だと思います。

case R.id.itTip:
    final Dialog tipCalculator = new Dialog(this);
    tipCalculator.setTitle("Tip Calculator");
    View contentView = View.inflate(this, R.layout.tip_layout, null);

    totalBill = (EditText) contentView.findViewById(R.id.editTBill);
    tips = (EditText) contentView.findViewById(R.id.editTTip);
    calculate = (Button) contentView.findViewById(R.id.bCalcTip);
    tvResult = (TextView) contentView.findViewById(R.id.tvTipResult);

    calculate.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "Calculate clicked", Toast.LENGTH_SHORT).show();
        }
    });

    tipCalculator.setContentView(contentView);
    tipCalculator.setCancelable(true);
    tipCalculator.show();
    break;

異なる点は、事前にビュー (contentView) をインフレートし、そのビューを具体的に検索して各ウィジェットを見つける場所を定義することです。

于 2013-07-08T04:33:53.957 に答える