14

我知道这似乎是一个重复的问题,但我真的无法找到相关主题的好答案。

关于什么是OnClick处理Button.
以下是我遇到的一些选项:

1 - 在方法上以编程方式定义侦听器OnCreate

button.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
        //do stuff
    }
});

2 -android:OnClick在 XML 上设置属性:

<Button android:id="@+id/btnDelete"
    ...
    android:OnClick="btnDelete_OnClick"/>

3 -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);
    }
}

4 - 创建一个OnClickListener类型为:

private OnClickListener onClickHandler = new OnClickListener(){

    @Override
    public void onClick(View v) {
        //stuff
    }
};

protected void onCreate(Bundle savedInstanceState) {
    ...
    button.setOnClickListener(onClickHandler);
}

当谈到 aButtonOnClick事件时,我总是更喜欢在 XML 上定义它,它只是更干净。

但是其他事件,例如OnItemClickfrom theListView或 the OnTimeSetfrom theTimePickerDialog呢?我看不到用于在 XML 上设置它的属性。我认为实现监听器接口是一个非常干净的解决方案,但这意味着我只能实现一次,如果我有两个相等的视图,我将不得不在同一个地方处理它们的事件。如果我使用选项 2 或 4,则在处理来自 UI 的不同视图的多个事件时可能会变得非常混乱。

如果事件处理有任何其他实现选项,我希望看到关于这个主题的其他意见。真的有替代方案可以定义为更好的替代方案,还是只是每个程序员的个人问题?

4

5 回答 5

3

让我尝试逐个解释:

案例# 1 这种方式会像创建按钮一样创建匿名类(每个按钮都需要新的监听器),而且它的可读性和成本都较低。

案例#2 其实如果你阅读这背后的代码,你会发现它使用反射来找到你的回调监听器(方法),并且它的可读性较差,并且使其他开发人员感到困惑。

案例# 3 这种方式很难导航,因为您无法确定当前按钮正在使用的侦听器的类型(我知道 eclipse 会突出显示this指向的方法,但是对于庞大的代码,我认为这会很困难找到)。

案例# 4 我认为这是实现监听器的最佳方式,易于导航,更具可读性,一个监听器可以处理所有相关事件(并且使用 eclipse,ctrl+click你可以去监听器),所以我推荐这个(我在工作中只使用这种方式)

我希望这个能帮上忙

于 2013-03-04T21:24:50.743 回答
1
  1. 如果我在课堂上只有一两个听众,我喜欢这种方法。比如列表视图的onItemClickListener. 有多个视图,它确实变得非常混乱。

  2. 我根本不使用android:onClick,只是因为我喜欢将我的代码保留在我的代码中。

  3. 当我有几个视图需要处理时,我喜欢这个。但是,我仍然喜欢保持我的onClick()代码稀疏。它通常以switchid 为结尾,一组类似的视图调用额外的方法来处理,类似handleDownVote()或类似的。这样,我所有的主要“处理”调用都在一个地方完成。

  4. 我不知道人们这样做了。我想它比#3 提供了更好的分组相似视图的能力,但我从来没有真正考虑过。也许我会试一试。

然而,归根结底,这是一个非常主观的问题,因为没有真正“正确”或“优化”的方式来做到这一点。如您所见,到目前为止,每个答案都不同。没有冒犯,但投票结束。

于 2013-03-04T21:37:29.887 回答
0

There is another possibility

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));
    ...
}

This avoids having to figure out what to do based on the view (button) that was clicked. Obviously you could have more than one parameter to the constructor to support specifying even richer actions without "hard-coding" resource ID's or button identities into the MyListener object.

于 2013-03-04T22:01:47.107 回答
0

首先 - 每个人都应该习惯阅读匿名内部类。它们很恶心,但它们被广泛使用,你会看到很多。

也就是说,我会选择 #1,因为它是本地化的 - 您会在添加它的位置看到您作为侦听器添加到您关注的按钮的内容。它允许监听多个按钮(与在类级别实现监听器相比)。

风格方面,我建议像这样实现具有单一方法的匿名内部类:

button.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
        //do stuff
    }});

这 ”}});” 是一个主要的眼睛 - 这是故意的。它像旧的“拇指酸痛”一样突出。这抓住了你的眼球,让你意识到正在发生一些特别的事情——匿名内部类定义的结束。匿名内部类可能难以阅读——这种丑陋实际上有助于提高可读性。

于 2013-03-04T23:31:26.147 回答
0

处理 Button 的 OnClick 事件的最佳方式取决于以下几点:

1. 没有你有的按钮。

Ans:如果你只有一个按钮,你可以使用第一种创建匿名类的方法。但是如果你有多个按钮,那么创建多个匿名 onClicklistener 是不好的。但与其他选择一起去

2.内存优化

Ans:如果您在 Activity 类上实现 OnClickListener 接口并将自引用传递给 Button,则 onclick 侦听器将保留对该活动对象的引用,因此将整个活动的对象保留在其中会很重,所以在这个方式具有 OnClickListener 类型的局部变量是更优化的方式。

因此,总体而言,最佳实践是使用 OnClickListener 类型创建一个局部变量,这是处理任何类型事件的最佳方式,而不仅仅是 Button 上的 onClick 事件。

于 2013-03-04T12:04:07.763 回答