我知道这似乎是一个重复的问题,但我真的无法找到相关主题的好答案。
关于处理OnClick
Button
事件的最佳方式,有很多问题。
以下是我遇到的一些选项:
OnCreate
方法上以编程方式定义侦听器:button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//do stuff
}
});
android:OnClick
属性:<Button android:id="@+id/btnDelete"
...
android:OnClick="btnDelete_OnClick"/>
OnClickListener
类上实现Activity
接口并将自引用传递给Button:public class MainActivity extends Activity implements OnClickListener{
@Override
public void onClick(View v) {
//do stuff
}
protected void onCreate(Bundle savedInstanceState) {
...
button.setOnClickListener(this);
}
}
OnClickListener
类型的字段:private OnClickListener onClickHandler = new OnClickListener(){
@Override
public void onClick(View v) {
//stuff
}
};
protected void onCreate(Bundle savedInstanceState) {
...
button.setOnClickListener(onClickHandler);
}
当谈到Button
和OnClick
事件时,我总是更喜欢在XML上定义它,它只是更干净。
但是OnItemClick
中的ListView
或OnTimeSet
中的TimePickerDialog
等其他事件呢?我没有看到在XML上设置它的属性。我认为实现Listener接口是一个非常干净的解决方案,但这意味着我只能实现一次,如果我有两个相同的视图,我将不得不在同一个地方处理它们的事件。如果我使用选项2或4,当从UI处理来自不同视图的多个事件时,它可能会变得非常混乱。
如果事件处理有任何其他实施方案,我希望看到有关此主题的其他意见。真的有一种替代方案可以被定义为更好的方案,还是只是每个程序员的个人事务?
答案 0 :(得分:2)
让我试着逐案解释:
案例#1 这种方式将创建匿名clases,就像创建按钮一样(每个按钮都需要新的监听器),并且其可读性和成本较低。
案例#2 实际上,如果你阅读了这背后的代码,你会发现它使用反射来找到你的回调的监听器(方法),它的可读性较差,并且让其他开发人员感到困惑。
案例#3
这种方式难以浏览,因为您无法使用当前按钮确定您正在使用的侦听器的类型(我知道eclipse将突出显示this
指向的方法,但是使用巨大的代码我认为它将会很难找到。)
案例#4
我认为这是实现监听器的最佳方式,易于导航,更易读,一个监听器可以处理所有相关事件(并且使用eclipse,只需ctrl+click
就可以转到监听器),所以 我推荐这个 (我在工作时只使用这种方式)
我希望这会有所帮助
答案 1 :(得分:1)
如果我在课堂上只有一个或两个听众,我喜欢这个方法。例如listview的onItemClickListener
。有多个视图,确实非常混乱。
我根本不使用android:onClick
,因为我喜欢将代码保存在我的代码中。
我喜欢这个,因为我有一些观点需要处理。但是,我仍然希望保持我的onClick()
代码稀疏。它最终通过id成为switch
,其中一组相似的视图调用其他方法来处理,例如handleDownVote()
或类似。这样,我的所有主要“处理”调用都在一个地方完成。
我不知道有人这样做过。我认为它提供了比#3更好的分组视图的能力,但我从未真正考虑过它。也许我会在一段时间内试一试。
答案 2 :(得分:0)
处理Button的OnClick事件的最佳方法取决于一些事情:
<强> 1。你没有按钮。
Ans:如果你只有一个按钮,你可以选择第一个创建annonymoous类的approch。 但是如果你有多个按钮,那么创建多个匿名的onClicklisteners就不好了。但要与其他选项一起使用
<强> 2。记忆优化
Ans:如果您正在Activity类上实现OnClickListener接口并将自引用传递给Button,那么onclick侦听器将保留对该活动对象的引用,因此将整个活动的对象保留在其中会很重,所以这样一个具有OnClickListener类型的局部变量是更优化的方式。
总的来说,最佳做法是使用OnClickListener类型创建局部变量是处理任何类型事件的最佳方式,而不仅仅是on Button上的onClick事件。
答案 3 :(得分:0)
还有另一种可能性
class MyListener implements onClickHandler{
public MyListener(SomeType parameter)
{
m_parameter = parameter;
}
@Override
public void onClick(View v) {
// do some stuff based on the value of m_parameter
}
private SomeType m_parameter;
};
protected void onCreate(Bundle savedInstanceState) {
...
findViewById(R.id.Button1).setOnClickListener(new MyListener(parameter1));
findViewById(R.id.Button2).setOnClickListener(new MyListener(parameter2));
...
}
这可以避免必须根据点击的视图(按钮)找出要做的事情。显然,构造函数可以有多个参数,以支持指定更丰富的操作,而无需将资源ID或按钮标识“硬编码”到MyListener对象中。
答案 4 :(得分:0)
首先 - 每个人都应该习惯于阅读匿名的内部课程。它们很粗糙,但它们被广泛使用,你会看到很多它们。
那就是说,我选择了#1,因为它是本地化的 - 你会看到你正在添加的内容作为你所关注的按钮所关注的按钮。它允许监听多个按钮(与在类级别实现监听器相比)。
样式方面,我建议使用单一方法的匿名内部类实现如下:
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//do stuff
}});
“}});”是一个主要的眼睛 - 这是故意的。它像老“拇指”一样突出。这会抓住你的眼睛,让你意识到一些特殊的东西正在发生 - 匿名内部类定义的结束。匿名内部类很难读 - 这种丑陋实际上有助于提高可读性。