使用循环设置按钮 onclicklistener

Using a loop to set the buttons onclicklistener

我正在尝试使用循环为每个按钮设置单击时的操作(因为大多数按钮只会 return 它们的文本值),但是我收到一条错误消息 "variable 'i' is accessed from within inner class, needs to be declared final".我该如何解决这个问题?

这是我得到的

String getValuesPressed(){

    for(int i = 0; i < buttonList.length; i++){

        buttonList[i].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(i == 0){//error occurs here
                    //do stuff
                }

            }
        });
    }
    return textOnScreen;
}

您可以将 i 的值复制到临时最终变量中作为 -

for (int i = 0; i < buttonList.length; i++) {
        final int finalI = i;
        buttonList[i].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (finalI == 0) {//error occurs here
                    //do stuff
                }
            }
        });
    }

您正在为每个按钮创建一个 anonymous class (View.OnClickListener),其中 class 中的 onClick() 方法与方法 getValuesPressed() 具有不同的作用域], 因此它无法访问局部变量 i.

解决方案包含在上面提供的 link 中:

An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

因此在循环中引入一个最终变量将解决错误:

String getValuesPressed(){

    for(int i = 0; i < buttonList.length; i++){
        final int j = i;
        buttonList[i].setOnClickListener(new View.OnClickListener() {
            @Override 
            public void onClick(View v) {

                if(j == 0){//error occurs here
                    //do stuff 
                } 

            } 
        }); 
    } 
    return textOnScreen; 
} 

您可以创建自己的侦听器,将位置作为参数来解决您正在使用匿名内部的事实 class。

private class MyClickListener implements View.OnClickListener {

    int position;

    public MyClickListener (int position) {
        this.position = position;
    } 

    @Override 
    public void onClick(View v) {
        if(position == 0){
            //do stuff 
        } 
    } 
} 

然后在你的循环中你可以像这样创建它

String getValuesPressed(){

    for(int i = 0; i < buttonList.length; i++){
        buttonList[i].setOnClickListener(new MyClickListener(i)); 
    } 

    return textOnScreen; 
}