2013-07-15 3 views
0

У меня очень простой вопрос, я очень новичок в Java, поэтому извиняюсь, если это тривиальное дело.Упрощение нескольких onclicklisteners, предназначенных для вызова того же действия

В одной ситуации в моем приложении вы получаете одинаковое количество точек для проверки каждой из серии CheckBoxes. Я мог бы установить OnClickListener для каждого, но это похоже на неэлегантное решение, поэтому вместо этого я хотел бы написать код, который говорит: «проверка любого из этих CheckBoxes дает тот же результат».

То, что я написал, к сожалению, не работает:

int[] ids = {R.id.cmCheckBox1, R.id.cmCheckBox2, R.id.cmCheckBox3, R.id.cmCheckBox4, R.id.cmCheckBox5, R.id.cmCheckBox6, R.id.ctCheckBox1, R.id.ctCheckBox2, R.id.ctCheckBox3}; 
final CheckBox[] checkBoxes = new CheckBox[ids.length]; 
for (int i = 0; i < ids.length; ++i) { 
    checkBoxes[i] = (CheckBox) findViewById(ids[i]); 
    checkBoxes[i].setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      if (checkBoxes[i].isChecked()) { 
       Global.score += 5; 
      } else { 
       Global.score -= 5; 
      } 
     } 
    }); 
} 

Для этого кода, я получаю сообщение об ошибке:

"Cannot refer to a non-final variable i in an inner class defined in a different method". 

токарной линии 3 в for (final int i = 0; i < ids.length; ++i) { не помогает, я угадать, потому что окончательная переменная не может быть изменена?

Любые предложения были бы очень благодарны!

ответ

0

Вы создаете анонимные классы внутри цикла for, это не то, что вы хотите делать.

Создайте свой собственный класс, который реализует OnClickListener, а затем добавьте его как слушателя ко всем вашим флажкам.

Edit: так как вы, кажется, возникают некоторые проблемы, вот толчок в правильном направлении -

checkBoxes[i].setOnClickListener(new MyOnClickListener(checkBoxes[i])); 

... 

class MyOnClickListener 
    implements OnClickListener 
{ 
    private CheckBox checkBox; 
    public MyOnClickListener(CheckBox box) 
    { 
     // maintain a reference to the CheckBox so we can see if it's checked! 
     this.checkBox = box; 
    } 

    public void onClick(View v) 
    { 
     // if this.checkBox is checked, then... 
    } 
} 
+0

Хорошо, я могу это исправить. Есть ли какая-то особая причина, почему не рекомендуется использовать анонимные классы? Это потому, что после этого они могут ссылаться на другие части программы или просто на чтение? – anunn

+0

Самая большая стоимость - это удобство и удобочитаемость кода, да. Плюс в этом случае заканчивается недостаточно гибким, так как вам нужно дать вашему слушателю ссылку на этот флажок, чтобы он мог знать, проверен ли он или нет. – roippi

+0

Я добавил пример, так как вы, кажется, боретесь с тем, как ссылаться на флажок внутри вашего слушателя. – roippi

1

Проблема в том, что ваш onClickListener не может ссылаться на i. Решение состоит в том, чтобы добавить конструктор в ваш onClickListener, добавить, что этот конструктор принимает значение для i и сохраняет его в переменной-члене onClickListener. Конечно, с таким кодом вы, вероятно, захотите сделать его именованным классом, а не анонимным для удобства чтения.

+0

Большое спасибо Гейб, я уверен, что это очень простые вещи, но могли бы вы дать мне пример как использовать конструктор для принятия значения i? – anunn

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