我知道这似乎是一个重复的问题,但是我真的无法找到一个关于相关主题的好答案。
关于处理Button
的OnClick
事件的最佳方法有很多问题。
以下是我遇到的一些选项:
1 -在OnCreate
方法上以编程方式定义侦听器:
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//do stuff
}
});
2 -在XML上设置android:OnClick
属性:
<Button android:id="@+id/btnDelete"
...
android:OnClick="btnDelete_OnClick"/>
3 -在Activity
类上实现OnClickListener
接口,并向Button传递一个自引用:
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onClick(View v) {
//do stuff
}
protected void onCreate(Bundle savedInstanceState) {
...
button.setOnClickListener(this);
}
}
4 -创建OnClickListener
类型的字段:
private OnClickListener onClickHandler = new OnClickListener(){
@Override
public void onClick(View v) {
//stuff
}
};
protected void onCreate(Bundle savedInstanceState) {
...
button.setOnClickListener(onClickHandler);
}
当涉及到Button
和OnClick
事件时,我总是喜欢在XML上定义它,这样更干净。
但是其他事件,比如ListView
中的OnItemClick
或TimePickerDialog
中的OnTimeSet
呢?我没有看到在XML上设置它的属性。我认为实现Listener接口是一个非常干净的解决方案,但这意味着我只能实现它一次,如果我有两个相等的视图,我将不得不在同一个地方处理它们的事件。如果我使用选项2或4,在处理来自UI的不同视图的多个事件时,可能会变得相当混乱。
我想看看关于这个主题的其他意见,如果有任何其他的选项来实现事件处理。是否真的存在一种可以被定义为更好的替代方案,或者这只是每个程序员的个人问题?
让我逐案解释:
案例# 1 这种方式创建匿名类的次数和创建按钮的次数一样多(每个按钮都需要新的侦听器),而且可读性差,成本高。
案例# 2 实际上,如果你阅读这背后的代码,你会发现它使用反射来找到回调的侦听器(方法),而且它的可读性较差,并使其他开发人员感到困惑。
案例# 3 这种方式很难导航,因为您无法确定当前按钮所使用的侦听器的类型(我知道eclipse将突出显示this
所指向的方法,但我认为有大量代码将很难找到)。
案例# 4 我认为这是实现侦听器的最佳方式,易于导航,更具可读性,一个侦听器可以处理所有相关事件(并且使用eclipse,只需ctrl+click
您就可以转到侦听器),所以我推荐这个(我在工作中只使用这种方式)
我希望这对你有帮助
-
如果类中只有一个或两个侦听器,我喜欢这种方法。例如listview的
onItemClickListener
。对于多个视图,它确实变得非常混乱。 -
我根本不使用
android:onClick
,只是因为我喜欢把我的代码保持在我的代码中。 -
当我有几个视图要处理时,我喜欢这样。然而,我仍然喜欢保持我的
onClick()
代码稀疏。它通常以switch
的id结束,类似的视图组调用额外的方法来处理,如handleDownVote()
或类似的。这样,我所有主要的"处理"调用都在一个地方完成。 -
我不知道人们会这样做。我认为它提供了比#3更好的对视图进行分组的能力,但我从未真正考虑过这一点。
归根结底,这是一个非常主观的问题,因为没有真正的"正确"或"优化"的方法来做到这一点。如你所见,到目前为止,每个答案都是不同的。无意冒犯,但投票结束。
处理按钮OnClick事件的最佳方法取决于以下几点:
1。
答:如果你只有一个按钮,你可以用第一种方法创建匿名类。但是如果你有多个按钮,创建多个匿名的onclicklistener是不好的。但是要与其他选项一起使用
2。记忆优化
答:如果你是实现OnClickListener接口上的活动类和传递一个自我引用的按钮比onclick侦听器将保持该活动对象的引用,所以它将是沉重的保持整个活动的对象在它,所以以这种方式一个局部变量与OnClickListener类型是更优化的方式。
所以总的来说,最好的做法是创建一个本地变量与OnClickListener类型是最好的方式来处理任何类型的事件,而不仅仅是onClick事件上的按钮。还有一种可能
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对象中。
首先,每个人都应该习惯阅读匿名内部类。它们很恶心,但它们被广泛使用,你会看到很多。
也就是说,我会选择#1,因为它是本地化的——你会看到你在添加它的位置添加了什么作为一个监听器到你关心的按钮。它允许监听多个按钮(相对于在类级别实现监听器)。
在风格方面,我建议使用单个方法的匿名内部类像这样实现:button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//do stuff
}});
"}});"很碍眼——这是故意的。它就像老的"拇指痛"一样突出。这引起了您的注意,并使您意识到正在发生一些特殊的事情—匿名内部类定义的结束。匿名内部类可能很难阅读——这种丑陋实际上有助于可读性。