简化几个用于调用相同操作的onclicklistener

时间:2013-07-15 13:14:22

标签: java android iteration

我有一个非常简单的问题,我对Java很新,所以如果这是一件小事就道歉。

在我的应用程序的一种情况下,您可以获得相同数量的点来检查一系列CheckBox中的每一个。我可以为每个设置一个OnClickListener,但这似乎是一个不优雅的解决方案,所以我想编写一些代码,说“检查这些CheckBox中的任何一个产生相同的结果。”

遗憾的是,我写的不起作用:

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) {没有用,我猜是因为最终变量无法修改?

非常感谢任何建议!

2 个答案:

答案 0 :(得分:1)

问题是你的onClickListener不能引用i。解决方案是向onClickListener添加一个构造函数,添加该构造函数获取i的值并将其保存到onClickListener的成员变量中。当然,有了这么多代码,你可能想让它成为一个命名类而不是一个可读性的匿名代码。

答案 1 :(得分:0)

你正在for循环中创建匿名类,这不是你想要做的事情。

创建自己的实现OnClickListener的类,然后将其作为侦听器附加到所有复选框。

编辑:因为你似乎遇到了一些麻烦,所以这是一个正确方向的推动 -

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...
    }
}