Java XML onClickListener与编程方法的优缺点

Java XML onClickListener与编程方法的优缺点,java,android,xml,Java,Android,Xml,我想找出哪种方法更适合在Android中绑定onClickListener 实现这一点有几种主要方法。我们可以在XML中使用android:onClick属性,这是一种编程方法: findViewById(R.id.button1).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { /

我想找出哪种方法更适合在Android中绑定
onClickListener

实现这一点有几种主要方法。我们可以在
XML
中使用
android:onClick
属性,这是一种编程方法:

   findViewById(R.id.button1).setOnClickListener(
       new View.OnClickListener() {
          @Override
          public void onClick(View v) {
             //Add some logic
          }
       }
   );
以及各种数据绑定库,如
ButterKnife
。为了简单起见,让我们把数据绑定库放在一边,重点讨论XML属性与编程方法

在我看来,XML属性的优越性在于以下原因:

  • 对于编程方法,我们总是必须为元素指定一个ID,但是对于XML属性,可以忽略它
  • 使用编程方法类,我们必须主动搜索视图中的元素(
    findViewById
    part),但是使用XML属性,Android为我们做这件事
  • 我们可以看到,编程方法类至少需要五行代码,但对于XML属性,三行代码就足够了
  • 使用编程方法,我们必须将方法命名为
    onClick
    ,但是使用XML属性,我们可以添加任何我们想要的名称,这将极大地提高代码的可读性
  • XML
    onClick
    属性是Google在API level 4发行版中添加的,这意味着它更加现代。新的语法几乎总是更好
  • 显然,我们不能将XML属性用于片段,但就活动而言,它似乎是一种更好的方法


    也就是说,根据我的经验,编程方法似乎更受欢迎。我错过什么了吗

    我更喜欢程序化方法,原因有两个:

    点击事件的集中管理:在这种情况下,您必须使用相同的方法来管理所有点击,而不是可以更改的自定义方法。例如:

    public class ActivityA extends Activity implements View.OnClickListener {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            findViewById(R.id.first).setOnClickListener(this);
            findViewById(R.id.second).setOnClickListener(this);
            findViewById(R.id.third).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.first:
                    // Manage click.
                    break;
    
                case R.id.second:
                    // Manage click.
                    break;
    
                case R.id.third:
                    // Manage click.
                    break;
            }
        }
    }
    
    性能:编程方法比XML方法性能更好,原因有二。第一,每次在XML中声明
    android:onClick
    属性时,都会实例化一个新的
    DeclaredOnClickListener
    。如果在同一个树中有多个
    视图
    ,则使用共享的单击侦听器会更有效。第二个是
    DeclaredOnClickListener
    在内部使用反射来调用方法

    不同组件中的相同模式:不能在
    片段中使用XML方法,因此必须将声明单击侦听器的方式从
    活动
    更改为
    片段
    。相反,如果使用编程方法,则在
    活动
    片段
    中应用相同的模式


    我还将分享我的个人经验:在过去,我第一次使用XML方法。现在,我从不在项目中使用它,因为如果您使用编程方法编写更多代码,我认为它更有序。

    我更喜欢编程方法,原因有两个:

    点击事件的集中管理:在这种情况下,您必须使用相同的方法来管理所有点击,而不是可以更改的自定义方法。例如:

    public class ActivityA extends Activity implements View.OnClickListener {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            findViewById(R.id.first).setOnClickListener(this);
            findViewById(R.id.second).setOnClickListener(this);
            findViewById(R.id.third).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.first:
                    // Manage click.
                    break;
    
                case R.id.second:
                    // Manage click.
                    break;
    
                case R.id.third:
                    // Manage click.
                    break;
            }
        }
    }
    
    性能:编程方法比XML方法性能更好,原因有二。第一,每次在XML中声明
    android:onClick
    属性时,都会实例化一个新的
    DeclaredOnClickListener
    。如果在同一个树中有多个
    视图
    ,则使用共享的单击侦听器会更有效。第二个是
    DeclaredOnClickListener
    在内部使用反射来调用方法

    不同组件中的相同模式:不能在
    片段中使用XML方法,因此必须将声明单击侦听器的方式从
    活动
    更改为
    片段
    。相反,如果使用编程方法,则在
    活动
    片段
    中应用相同的模式

    我还将分享我的个人经验:在过去,我第一次使用XML方法。现在,我从不在项目中使用它,因为如果您使用编程方法编写更多代码,我认为它更有序。

    使用它,这样您就不需要为每个视图重复调用
    findViewById(int)
    。将为布局中具有ID的每个视图生成公共最终字段。绑定在视图层次结构上执行一次传递,提取具有ID的视图对于多个视图,此机制可能比调用
    findViewById(int)
    更快。

    MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());
    
    设置单击Listener以获得必要的视图,如下所示

    binding.button1.setOnClickListener(this);
    binding.button2.setOnClickListener(this);
    
    处理
    onClick(View)
    实现中的所有按钮单击事件,这样就不需要为每个按钮添加单独的匿名侦听器应尽可能避免匿名内部类,因为匿名类将包含对外部类的隐式引用。

     @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.button1:
                   onClickButton1();
                    break;
    
                case R.id.button2:
                   onClickButton2();
                    break;
    
    
            }
        }
    
    因此,我们可以得出结论,的编程方法似乎是首选。

    使用,这样您就不需要为每个视图重复调用
    findViewById(int)
    。将为布局中具有ID的每个视图生成公共最终字段。绑定在视图层次结构上执行一次传递,提取具有ID的视图对于多个视图,此机制可能比调用
    findViewById(int)
    更快。

    MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());
    
     @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.button1:
                   onClickButton1();
                    break;
    
                case R.id.button2:
                   onClickButton2();
                    break;
    
    
            }
        }
    
    设置单击Listener以获得必要的视图,如下所示

    binding.button1.setOnClickListener(this);
    binding.button2.setOnClickListener(this);
    
    处理
    onClick(View)
    实现中的所有按钮单击事件,这样就不需要为每个按钮添加单独的匿名侦听器应该尽可能避免匿名内部类,因为