2013-07-08 2 views
0

Я вызываю из меню Item a Dialog, и у меня есть кнопка внутри этого диалога и пытаюсь что-то сделать, когда я нажимаю кнопку. Часть моего кода это как следует:setOnClickListener для кнопки внутри onOptionsItemВыбранный причиной сбоя приложения

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, он отлично работает и показывает диалог отлично. Но всякий раз, когда я пытаюсь использовать Listener, он падает. Я проверил в LogCat и на самом деле не мог четко понять проблему. Надеюсь, кто-нибудь может мне помочь.

+0

Попробуйте заменить getApplicationContext() с помощью v.getContext() –

+0

На самом деле я пробовал держать пустое внутри этого метода OnClick (View v), так что он сбой –

+0

«Рассчитывает» 'null'? Попробуйте отобразить в журнале, вызовите это перед 'calculate.setOnClickListener()', 'Log.d (« Button Calculate »,« Is null: »+ calculate == null);' – Geros

ответ

0

Я думаю, что проблема заключается в том, что вы пытаетесь найти представление, прежде чем вы его на самом деле показали, это заставляет «вычислять» значение null при попытке назначить onClickListener и тем самым исключить исключение нулевого указателя.

Для более подробного объяснения 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) и определить, где искать каждый виджет, просматривая этот вид.

+0

супер! Я также нашел решение почти таким же образом, когда я раздул View с LayoutInflater, но не знал, почему он работает. Теперь это понятно! ... но может ли это работать, если я вызову эти findViewById и OnclickListener после tipCalculator.show()? –

+0

Эй, теперь я помню, что я пробовал это раньше в ListView, когда я нажимаю на него, вызывается так же, как и у Button, и там я использовал тот же подход, что и мой код, и он работал нормально! :/..... Я думаю, что должно быть соединение с этими значениями Null с меню? –

Смежные вопросы