繁体   English   中英

XML onClickListener与程序设计方法的优缺点

[英]Pros and cons of XML onClickListener vs programatic approach

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

有几种主要方法可以实现此目的。 我们可以使用XML (一种编程方法)中的android:onClick属性:

   findViewById(R.id.button1).setOnClickListener(
       new View.OnClickListener() {
          @Override
          public void onClick(View v) {
             //Add some logic
          }
       }
   );

还有各种数据绑定库,例如ButterKnife 为了简单起见,我们将数据绑定库放在一边,而将重点放在XML属性VS编程方法上。

我认为,由于以下原因,XML属性是优越的:

  1. 使用编程方法,我们总是必须为元素指定ID,但是使用XML属性可以将其省略。
  2. 使用编程方法类,我们必须主动搜索视图内部的元素( findViewById部分),但是使用XML属性,Android会为我们完成此操作。
  3. 如我们所见,程序化方法类至少需要五行代码,但是使用XML属性,三行代码就足够了。
  4. 使用编程方法,我们必须将方法命名为onClick ,但是使用XML属性,我们可以添加所需的任何名称,这将大大有助于代码的可读性。
  5. Google在API级别4版本中添加了XML onClick属性,这意味着它更加现代。 而且新语法几乎总是更好。

显然,我们不能将XML属性与Fragments一起使用,但是就Activity而言,对我来说,这似乎是一种更好的方法。

就是说,根据我的经验,程序化方法似乎是首选。 我想念什么吗?

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

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

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 如果同一棵树中有多个View ,则拥有一个共享的Click侦听器会更有效。 第二个是DeclaredOnClickListener内部使用反射来调用您的方法。

跨不同组件的模式相同 :不能在Fragment使用XML方法,因此必须将声明Click监听器的方式从Activity更改为Fragment 相反,如果您使用编程方法,则可以在ActivityFragment应用相同的模式。

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

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

MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());

设置clickListener以获取必要的视图,如下所示。

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;


        }
    }

因此,我们可以得出结论, 采用数据绑定程序设计方法似乎是首选。

Xml方法与程序方法:

使用xml方法的专业人士

  • 您可以在每个元素上定义用户定义的方法
  • 用户定义的方法将具有完全限定的名称
  • 具有完全限定名称的声明方法可提高可读性

使用程序化方法的专业人士

  • 对于每个元素的每个“ onclick”事件,您都无需定义方法
  • 以编程方式,这可以通过重写View.OnClickListener仅声明一个onclick方法来实现。

结论 :这完全取决于开发人员和要求-

如果一个活动中的单击方法太多,则不能选择编程方法,因为遵循xml方法并为每个元素编写过多的单击方法将非常繁琐。

另外,如果没有。 onclick的活动与其说是使用xml方法的常识,不如说是一项活动,因为它不会编写太多的方法,并且会增加代码的可读性。

xml方法示例

main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="92dp"

        android:onClick="clickFunc1"

        android:text="Click me" />
           <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="92dp"

        android:onClick="clickFunc2"

        android:text="Click me" />

</RelativeLayout

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void clickFunc1(View view){
        Toast.makeText(MainActivity.this, "Button1 Clicked",    Toast.LENGTH_SHORT).show();
    }

    public void clickFunc2(View view){
        Toast.makeText(MainActivity.this, "Button2 Clicked",    Toast.LENGTH_SHORT).show();
    }


}

程序化方法

main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="92dp"
        android:text="Click me" />
           <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="92dp"
        android:text="Click me" />
           <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="92dp"
        android:text="Click me" />

</RelativeLayout>

MainActivity.java

public class MainActivity extends Activity implements View.OnClickListener {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
               Toast.makeText(MainActivity.this, "Button1 Clicked", Toast.LENGTH_SHORT).show();
                break;

            case R.id.button2:
               Toast.makeText(MainActivity.this, "Button2 Clicked", Toast.LENGTH_SHORT).show();
                break;

            case R.id.button3:
              Toast.makeText(MainActivity.this, "Button3 Clicked",  Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM