XML中的Android onClick与OnClickListener


86

我意识到以前有人问过类似措词的问题,但这是不同的。我在开发android应用程序时还很陌生,关于android:onclick=""XML属性和setOnClickListener方法之间的区别,我有三个问题。

  1. 两者之间有什么区别?在编译时或运行时或在两者时发现两种实现之间的区别吗?

  2. 哪些用例有利于哪种实现?

  3. Android中使用片段对实现选择有何不同?


1
对于#2:使用xml时应小心,onclick因为需要确保每个类都实现该方法。这是假设您多次使用布局。但是,如果要有一个Java接口来确保该方法已在实现该方法的所有类中使用,则不必担心。
Uxonith 2014年

您所描述的Java接口是否与扩展或隐含OnClickListener几乎相同?
KG6ZVP 2014年

我之前已经研究过这个问题,但我认为它还有很多要优先考虑的地方,但是很抱歉,我已经说了一段时间了,不能说更多。我喜欢android:onclick方便的时候,但是我知道有时候它会引起问题,我也不记得了:)
Uxonith 2014年

xml onClick不适用于在API级别19中动态膨胀的嵌套布局元素
Amit Kaushik,2016年

1
我很少见过其他实现android:onClick的人提供的代码,当您浏览别人的代码时,这是最令人困惑的。因为它没有setOnClickListener的所有可能性,所以我认为几乎每个人都只使用setOnClickListener
Christian

Answers:


122

OnClickListener与OnClick之间的区别:

  • OnClickListener是您需要实现的接口,可以将其设置为Java代码中的视图。
  • OnClickListener是等待某人实际单击的东西,onclick确定当某人单击时会发生什么。
  • 近期,android在视图中添加了一个名为android:onclick的xml属性,该属性可用于直接在视图活动中处理点击,而无需实现任何接口。
  • 如果需要,您可以轻松地将一个侦听器实现与另一个侦听器实现交换。
  • OnClickListener使您能够将click事件的操作/行为与触发事件的View分开。虽然对于简单的情况而言,这并不是什么大问题,但是对于复杂的事件处理,这可能意味着更好的代码可读性和可维护性
  • 由于OnClickListener是一个接口,实现它的类在确定处理事件所需的实例变量和方法方面具有灵活性。同样,在简单情况下这不是什么大问题,但是对于复杂情况,我们不想将与事件处理相关的变量/方法与触发事件的View代码混合在一起。
  • XML Layout中具有函数绑定的onClick是onClick和它将调用的函数之间的绑定。该函数必须具有一个参数(“视图”)才能使onClick起作用。

两者的功能相同,只是一个通过Java代码设置,另一个通过xml代码设置。

setOnClickListener代码实现:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

XML实施:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

性能:

两者的性能相同。编译时将Xml预解析为二进制代码。因此Xml中没有开销。

局限性:

android:onClick适用于API级别4以上,因此,如果您的目标是<1.6,则无法使用它。


`Xml在编译时被预先解析为二进制代码`此语句的确切含义是什么?由于我已经看到清单文件中包含android:onClick的apk的dexcode,但是我没有找到任何明确设置侦听器的
VicX 2015年

很棒的解释。+1
Zia Ur Rahman

1
实际上,XML中有一些开销。首次单击该按钮时,将使用反射来确定应调用的方法。但是,对于大多数用例来说,这可能可以忽略不计(过早的优化是万恶之源)。
Yoel

21

令我震惊的是,没有人谈论这件事,但要小心,尽管android:onClickXML似乎是处理单击的一种便捷方法,但setOnClickListener实现除了添加之外还做了其他事情onClickListener。确实,它使view属性clickable为true。

尽管在大多数Android实现中这可能不是问题,但根据电话构造函数的说法,button始终默认为clickable = true,但某些电话模型上的其他构造函数在非Button视图上可能具有默认的clickable = false。

因此,仅设置XML是不够的,您必须一直考虑添加android:clickable="true"非按钮,并且如果您的设备的默认设置为clickable = true,并且甚至忘记一次放置此XML属性,您都不会注意到在运行时出现问题,但是当它掌握在客户手中时,它将获得市场反馈!

此外,我们永远无法确定proguard将如何混淆和重命名XML属性和类方法,因此不能百分百保证它们一天都不会出现错误。

因此,如果您从不希望遇到麻烦而从未考虑过,最好使用setOnClickListener带有注释的ButterKnife之类的库@OnClick(R.id.button)


1
您是否有任何经验(或发现在某处)使用时由于混淆而导致错误发生android:onClick
阿克拉姆

谢谢你,先生!您的回答非常有帮助!
Yi Shen

12

只是:

如果您使用android:onClick = "someMethod" xml,它将public void someMethod在您的Activity类中查找。OnClickListener直接从您的Activity中调用,它与某些特定链接有关View。例如someButton.setOnClickListener,在下面的代码中,当someButton按下时必须说些什么。

希望能帮助到你 :)


4

如前所述:它们都是增加对事件(在本例中为“单击”事件)的响应的方式。

我会在逻辑和表示之间进行分离,就像在HTML / JavaScript世界中所做的那样:保留XML用于表示,并通过代码添加事件侦听器。


1
同意,除非它是一个具有某些简单行为的非常小的应用程序,否则所有执行代码都应保持独立且组织良好,最好使用单独的方法
OzzyTheGiant

0

如果您只有一种方法使用多个按钮,建议您使用Java。但是,如果您具有使用一种特定方法的按钮,则XML中的onClick会更好。


0

始终使用android:onClick属性会更方便,除非您有充分的理由不这样做,例如,例如在运行时实例化Button或需要在Fragment子类中声明单击行为。


3
我很少见过其他实现android:onClick的人提供的代码,当您浏览别人的代码时,这是最令人困惑的。因为它没有setOnClickListener的所有可能性,所以我认为几乎所有人都只使用setOnClickListener
Christian

0

您可能要以编程方式设置的原因有两个OnClickListener。第一个是您是否想在应用程序运行时更改按钮的行为。您可以将按钮完全指向另一种方法,也可以通过将按钮设置为OnClickListener不执行任何操作来禁用按钮。

使用onClick属性定义侦听器时,视图仅在其主机活动中查找具有该名称的方法。通过编程设置an,OnClickListener可以从主机活动以外的其他位置控制按钮的行为。当我们使用时Fragments,这将是非常相关的,它们基本上是微型活动,使您可以构建具有自己生命周期的可重用视图集合,然后将其组合成活动。由于片段OnClickListeners不是活动,因此始终需要使用片段来控制其按钮,并且不会在onClick中定义的侦听器中进行搜索。


-2

我认为它们之间的主要区别是:

OnClick:当您用手指单击按钮时。

OnClickListner:用各种代码实现可能是一个更广泛的选择。

例如,当您键入URL“ ymail.com”时,雅虎会从浏览器中找到您的用户名和密码,然后启用点击状态按钮以打开您的邮件。此操作仅应在onClickListener中实现。

这是我的主意!


这很有趣,但还有更多。您应该宁愿发表评论。
Dakatine
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.