OnClickListener внутри цикла, создающего исключение IndexOutOfBounds


Я пытаюсь создать то, что в основном является списком карт, повторяющихся одна за другой, основываясь на массиве, который у меня есть через цикл.

По какой-то причине, однако, установка моего OnClickListener внутри цикла вызывает исключение OOB, но из того, что я вижу, это не должно быть так, что я ценю быть указано в правильном направлении.

Мой цикл:

for(FAQNumber = 0; FAQNumber < questions.length; FAQNumber++){
    stack.add(new FAQCard(questions[FAQNumber], answers[FAQNumber]));
    (stack.get(FAQNumber)).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle bundle = new Bundle();
            bundle.putSerializable("title", questions[FAQNumber]);
            bundle.putSerializable("position", FAQNumber);
            startActivity(new Intent(getActivity().getBaseContext(), QuestionAnswer.class).putExtras(bundle));
        }
    });
}

questions это массив, объявленный ранее в методе, содержащий всего несколько строк. И stack ведет себя как список.

Я получаю ошибка OOB на bundle.putSerializable("title", questions[FAQNumber]);, когда он пытается добавить questions[5] (Если мой questions[] содержал 5 значений). Но я не понимаю, как это происходит, потому что цикл должен остановиться, прежде чем FAQNumber будет равно 5?

Все, что я пытаюсь сделать с вышеуказанным циклом, - это передать правильный вопрос в пакет, чтобы при нажатии на карту вопросы совпадали.

В любом случае, любая помощь ценится!

2 3

2 ответа:

FAQNumber, по-видимому, определяется вне цикла for, а не внутри него. Это означает, что он продолжает существовать после завершения цикла ... это намеренно? Если в questions есть 5 элементов, то после завершения цикла Факномер будет равен 5 (из-за последнего FAQNumber++).

Метод OnClickListener'S onClick(View v) не вызывается до тех пор, пока кнопка не будет фактически нажата. В это время он ищет номер Факна , который теперь равен 5. Ключевая вещь, которую нужно понять здесь, это то, что когда вы поместите FAQNumber в метод onClick, он будет фактически искать текущее значение FAQNumber в момент щелчка, а не в момент, когда вы определили метод. Причина, по которой вы получаете OutOfBoundsException в этой строке, заключается не в том, что ошибка происходит во время выполнения цикла, а в том, что поведение нажатия кнопки находится здесь, поэтому именно здесь возникает ошибка. Ваш цикл на самом деле выполняется просто отлично.

Вместо этого вы захотите сохранить FAQNumber в качестве экземпляра переменная в представлении, которое вы щелкаете, выглядит так:

for(int i = 0; i < questions.length; i++) {
  stack.add(new FAQCard(questions[i], answers[i]));
  // Replace YourViewClass with whatever you're getting off the stack
  YourViewClass obj = (stack.get(FAQNumber));
  obj.setFaqNumber(i); // You'll need to add this method
  obj.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Bundle bundle = new Bundle();
        // You'll need to add the getFaqNumber() getter as well
        bundle.putSerializable("title", questions[getFaqNumber()]);
        bundle.putSerializable("position", getFaqNumber());
        startActivity(new Intent(getActivity().getBaseContext(), QuestionAnswer.class).putExtras(bundle));
    }
});

В дополнение к ответу @hatboysam я также получил его работу, изменив на некоторое время:

while(FAQNumber < questions.length){
    final int i = FAQNumber;
    final FAQCard FAQ = new FAQCard(questions[FAQNumber], answers[FAQNumber]);
    FAQ.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Create a new bundle to pass to the browser
            Bundle bundle = new Bundle();
            // Inform which feed item was selected
            bundle.putSerializable("title", questions[i]);
            bundle.putSerializable("position", i);
            // Start the new activity and pass on the bundle
            startActivity(new Intent(getActivity().getBaseContext(), QuestionAnswer.class).putExtras(bundle));
        }
    });
    stack.add(FAQ);
    FAQNumber++;
};