有四种方法可以将onClickListener添加到可点击的视图(例如按钮):
所以我的问题是,你如何选择其中一种实现技术而不是另一种?根据某些条件是否有最佳实践,还是仅仅是程序员偏好的问题?
答案 0 :(得分:4)
这里我们使用所谓的回调模式。
public class Button {
private Callback callback;
public Button(Callback callback) {
this.callback = callback;
}
public void update() {
// Check if clicked..
callback.onClick(this);
}
public interface Callback {
public void onClick(Button Button);
}
}
Button b = new Button(new Callback() {
@Override
public void onClick(Button b) {
System.out.println("Clicked");
}
});
在我们的例子中,onClick处理程序实现了View.OnClickListener接口。
关键点:
1)XML文件中的属性只能用于活动,因为 @Karakuri 提到它使用慢的反射。
2)匿名内部类具有访问封闭类成员的特殊规则(检查[1],[2])。在某些情况下可能发生内存泄漏(例如使用AsyncTask,Handlers进行线程处理)。
3)在这里,您可以完全访问封闭类的成员。
4)是3d的变体。
可读性取决于您的处理程序大小,小逻辑可以内联,但对于较大的代码块,请考虑3d和4th。
答案 1 :(得分:2)
我从不使用onClick
属性,因为它将布局与特定的Activity绑定(它必须通过反射找到方法)。它不适用于碎片。
选项2和3实际上是相同的。如果您想将私有成员用作多个视图的OnClickListener
,则选项3可能更有利。
选项4接近选项3.一个关键的区别是它改变了类声明,因此如果保持类声明不受接口实现的影响很重要(或者你可能需要保持二进制兼容性)某种情况),您可能不想使用此选项。
我的建议是避免使用选项1,并选择最符合您代码风格的选项。您也不需要在代码中的每个位置使用相同的方法。
答案 2 :(得分:0)
使用OnClickListener
有四种方法。
要在方法调用站点中定义OnClickListener
。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = findViewById(R.id.myButton);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
});
}
}
避免这种情况的第一个原因是因为它使onCreate
方法变得混乱。当您要从多个视图观察点击事件时,这一点变得更加明显。
避免这种情况的下一个原因是,如果多个按钮应该执行相同操作,则它不会促进代码重用。
第二种方法与第一种几乎相同,除了在类中分配了对field的实现。
public class MainActivity extends AppCompatActivity {
private View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = findViewById(R.id.myButton);
button.setOnClickListener(clickListener);
}
}
这种方法与第一种方法几乎相同,唯一的优点是该方法可以重用于多个按钮。
这种方法是声明一个内部类来实现OnClickListener
。如果将其多次使用,最好将实例定义为字段。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = findViewById(R.id.myButton);
button.setOnClickListener(new ButtonClick());
}
class ButtonClick implements View.OnClickListener {
@Override
public void onClick(View v) {
// do something
}
}
}
这种方式的优点是它有助于组织代码。您可以轻松地折叠此内部类,而不必理会它,直到需要查看它为止。
另一个很好的理由是,它可以在公共类中打开并在其他应用程序区域中重用。
第四种方法是使用Activity来实现OnClickListener
。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = findViewById(R.id.myButton);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// do something
}
}
这种方法的第一个缺点是在Activity中创建了一个公共方法,因此在调用this
时应该通过setOnClickListener
活动。
避免这种方式的第二个原因是,如果添加了另一个按钮,则应确定单击了哪个按钮。然后,您应该使用switch()
或if()
语句。之所以无法执行,是因为每次点击都会浪费一个或几个循环。
这种方式的最后一个缺点是难以组织课程。在示例中,您有一个实现多个接口的活动。突然之间,这些接口中的所有方法都交织在一起,在将方法添加到某些接口后,这一点变得更加明显。同样,现在您也无法使用名为onClick
的方法添加接口。
这两种方法之间有些区别,但是您应该根据自己的代码和需求选择方式