如何管理动态创建按钮的 onClickListener?

huangapple go评论91阅读模式
英文:

How can I manage onClickListener of a dynamically created button?

问题

我正在尝试根据用户选择创建'n'个按钮。按钮的数量可以从1到3不等。然而,当我尝试根据按下的按钮更新变量时,我遇到了困难。它显示错误消息:"在 lambda 表达式中使用的变量应为 final 或 effectively final"。我理解这个错误,但无法弄清楚如何解决这个问题。这是我的示例代码:

for (int i = 0; i < options; i++) {
    Button button = new Button(this);
    button.setId(position);
    buttons[i] = button;
    buttons[i].setOnClickListener(v -> {
        tempToMaintain.setValue(listParameters.get(i));
    });
}
'options' 包含要创建的按钮数量,tempToMaintain 是从 Firebase 引用的变量。我试图从列表中获取值并在 Firebase 上更新它。我该如何实现这一点,非常感谢您的帮助。
英文:

I'm trying to create 'n' buttons based on the option user has selected. The buttons can range from 1 to 3. However I'm having difficulty when I try to update the variable depending upon the button pressed. It gives the error "Variable used in lambda expression should be final or effectively final". I understand the error but can't figure out how I can resolve this issue. Here is my sample code:

        for (int i = 0; i &lt; options; i++) {
            Button button = new Button(this);
            button.setId(position);
            buttons[i] = button;
            buttons[i].setOnClickListener(v -&gt; {
                tempToMaintain.setValue(listParameters.get(i));

            });
        }

'options' contain the number of buttons to create, tempToMaintain is a variable that is referenced from Firebase. I'm trying to get the value from the list and update it on Firebase. How can I achieve this, any help is greatly appreciated.

答案1

得分: 0

在Java中,你不能在lambda表达式以及匿名内部类中使用非final(还有非effectively-final)的变量。

你可以通过创建一个实现了View.OnClickListener接口的类,将变量i作为构造参数传递给它,从而摆脱lambda表达式。

例如:

class MyButtonClickListener implements View.OnClickListener {
   private int parameterIndex;

   public MyButtonClickListener(int parameterIndex) {
      this.parameterIndex = parameterIndex;
   }

   public void onClick(View v) {
      tempToMaintain.setValue(listParameters.get(parameterIndex));
   }
}

就是这样。如果新的类实例不能在上下文中访问tempToMaintainlistParameters,则将它们作为构造参数传递(就像我们在parameterIndex中所做的)。

现在,你可以将clickListener事件处理程序的绑定更改为:

for (int i = 0; i &lt; options; i++) {
   Button button = new Button(this);
   button.setId(position);
   buttons[i] = button;
   buttons[i].setOnClickListener(new MyButtonClickListener(i));
}

希望对你有所帮助。

英文:

in Java you can't use non-final (and also non-effectively-final) variables in lambda as well as in anonymous inner classes.

You could get rid of the lambda expression by creating a class that implements the View.OnClickListener interface and give it the variable i as a constructor parameter.

for example:

class MyButtonClickListener implements View.OnClickListener {
   private int parameterIndex;

   public MyButtonClickListener(int parameterIndex) {
      this.parameterIndex = parameterIndex;
   }

   public void onClick(View v) {
      tempToMaintain.setValue(listParameters.get(parameterIndex));
   }
}

And that should be it. Pass tempToMaintain and listParameters as constructor parameters (just like we did with parameterIndex) if your new class instances cannot contextually access them.

Now you can change the binding to the clickListener event handler to look like:

for (int i = 0; i &lt; options; i++) {
   Button button = new Button(this);
   button.setId(position);
   buttons[i] = button;
   buttons[i].setOnClickListener(new MyButtonClickListener(i));
}

Hope this helps.

huangapple
  • 本文由 发表于 2020年3月16日 02:11:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/60696095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定