【问题标题】:OnClickListener inside a loop throwing IndexOutOfBounds Exception循环内的 OnClickListener 抛出 IndexOutOfBounds 异常
【发布时间】:2013-06-23 23:41:54
【问题描述】:

我正在尝试根据我通过循环获得的数组创建基本上是一张又一张重复的卡片列表。

但由于某种原因,将我的 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 的行为就像一个列表。

bundle.putSerializable("title", questions[FAQNumber]); 在尝试添加 questions[5] 时出现 OOB 错误(如果我的 questions[] 包含 5 个值)。但我不明白这是怎么发生的,因为循环应该在 FAQNumber 等于 5 之前停止?

我对上述循环所做的只是将正确的问题传递给捆绑包,以便在按下卡片时,问题匹配。

无论如何,感谢您的帮助!

【问题讨论】:

    标签: android for-loop onclick indexoutofboundsexception


    【解决方案1】:

    FAQNumber 似乎是在 for 循环外部而不是内部定义的。这意味着它在循环完成后继续存在......这是故意的吗?如果questions 中有 5 个项目,则循环终止后,FAQNumber 将等于 5(由于最后一个 FAQNumber++)。

    在实际单击按钮之前,不会调用OnClickListeneronClick(View v) 方法。此时,它正在寻找FAQNumber 现在等于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));
        }
    });
    

    【讨论】:

    • 搞定了,谢谢!从来不知道 OnClick 是这样设置的,我认为它们被设置为稍后触发的视图
    • 它们被设置为稍后触发,但事件处理程序中的代码在点击时执行。
    • @hatboysam 另外,它在外部定义的原因是因为 Eclipse 抱怨它需要是 final,当然它不能被循环迭代。
    【解决方案2】:

    除了@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++;
    };
    

    【讨论】:

    • 这里重要的不是while,而是int i 是循环的局部变量和final,因此在OnClickListener 中被视为常量。
    猜你喜欢
    • 2014-04-03
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    相关资源
    最近更新 更多