在 Android 中实现 View.OnClickListener 的最佳方式

新手上路,请多包涵

假设我们有一个有很多视图的活动,要注册 OnClickListener

最常见的实现方式是让 Activity-Subclass 实现 OnClickListener,如下所示:

 public class ActivityMain extends Activity implements View.OnClickListener
{
    @Override
    public void onClick(View view)
    {
        switch (view.getId())
        {
            //handle multiple view click events
        }
    }
}

我喜欢实现它的方式是在 Activity-Subclass 中创建一个私有类,并让该内部类实现 OnClickListener:

 public class ActivityMain extends Activity implements View.OnClickListener
{
    private class ClickListener implements View.OnClickListener
    {
        @Override
        public void onClick(View view)
        {
            switch (view.getId())
            {
                //handle multiple view click events
            }
        }
    }
}

这样代码看起来更有条理也更容易维护。

此外,谈到“Is-a”、“Has-a”关系,后者似乎是一种很好的做法,因为现在 Activity-Subclass 将与 ClickListener 建立“Has-a”关系。在前一种方法中,我们会说我们的活动子类“是一个”ClickListener,这并不完全正确。

请注意,我不关心后者会导致的内存开销。

另外,在xml中添加onClick标签是完全没有问题的。

那么,真正实现 ClickListener 的最佳方式是什么?

请不要建议任何库,如 RoboGuice 或 ButterKnife 等。

更新:

我想分享一下我最终采用的方法。

我直接在Activity/Fragment中实现监听器。

就 OOP 设计而言。 “HAS-A” 方法没有提供任何实际好处,甚至会占用更多内存。考虑到我们将为我们实现的每个类似侦听器创建的嵌套类的数量(以及内存开销),显然应该避免这种方法。

原文由 Sarthak Mittal 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 981
2 个回答

首先,Android 没有定义关于注册点击监听器的最佳实践。这完全取决于您的用例。

实施 View.OnClickListener 活动接口是可行的方法。由于Android反复强烈推荐接口实现无论是Activity还是Fragment。

现在正如您所描述的:

 public class ActivityMain extends Activity implements View.OnClickListener
{
    private class ClickListener implements View.OnClickListener
    {
        @Override
        public void onClick(View view)
        {
            switch (view.getId())
            {
                //handle multiple view click events
            }
        }
    }
}

这是你的方法。现在这是您的实现方式,如果您不关心内存开销,这没有任何问题。但是创建内部类和实现 View.OnClickListener 的好处是什么?

所以这只是一个讨论,而不是获得实现 View.OnClickListener 的最佳解决方案,因为如果你从每个人的实际角度出发,你将寻求一个简单且内存效率高的解决方案。

所以我更喜欢传统的方式。它使事情变得简单和高效。检查下面的代码:

 @Override
public void onClick(View view)
{
    switch (view.getId())
    {
        //handle multiple view click events
    }
}

PS:您的方法肯定会增加代码行数:P;)

原文由 kamal vaid 发布,翻译遵循 CC BY-SA 3.0 许可协议

首先让我们在这里弄清楚基础知识..

通过实现一个接口,你的类不会变成那样……就像你说的那样:

“我们的活动子类“是一个”ClickListener,这并不完全正确。”

如果你的类扩展了,你的类只能有“Is-a”关系,在这种情况下是 Activity 。实现一个接口意味着它可以表现得像接口设置了它的契约一样。

一个例子:

类 Peter extends Human .. 意味着 Peter 是一个人..

类 Peter 还可以实现程序员、音乐家、丈夫等,这意味着 Peter 可以像上面那样表现。

至于最佳实践,您可以创建一个完全独立的类来实现 OnClickListener 如下所示:

 class MyListener implements View.OnClickListener{

  @Override
public void onClick(View view) {
        // do whatever you want here based on the view being passed
    }

}

在你的主要 Activity 你可以实例化 MyListener 并调用 onClick() 并在其中传递你的观点:

 MyListener listener = new MyListener();

Button b = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button)findViewById(R.id.button);
    listener.onClick(button);
   }

原文由 Sharp Edge 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题