XML 中的 Android onClick 与 OnClickListener

Posted

技术标签:

【中文标题】XML 中的 Android onClick 与 OnClickListener【英文标题】:Android onClick in XML vs. OnClickListener 【发布时间】:2014-02-14 16:46:27 【问题描述】:

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

    两者有什么区别?两种实现之间的区别是在编译时还是运行时发现的,还是两者兼而有之?

    哪些用例有利于哪种实施?

    在 Android 中使用 Fragment 对实现选择有何不同?

【问题讨论】:

对于 #2:使用 xml onclick 时应该小心,因为您需要确保每个类都实现该方法。这是假设您多次使用该布局。但是,如果您有一个 java 接口来确保该方法在所有实现它的类中,您就不必担心。 没有你描述的 java 接口与扩展或实现 OnClickListener 几乎相同吗? 我以前研究过这个,我认为它比偏好多一点,但很抱歉我不能说更多,因为已经有一段时间了。我喜欢方便的android:onclick,但我知道有时它会引起问题,我也不记得了:) xml onClick 不适用于在 API 级别 19 中动态膨胀的嵌套布局元素 我很少看到其他人实现 android:onClick 的代码,当您查看其他人的代码时,这是最令人困惑的。因为它没有 setOnClickListener 的所有可能性,在我看来几乎每个人都只使用 setOnClickListener 【参考方案1】:

OnClickListener 与 OnClick 的区别:

OnClickListener是你需要实现的接口,可以设置 在java代码中查看。 OnClickListener 等待某人 要实际点击,onclick 确定当有人 点击。 最近 android 为视图添加了一个 xml 属性,称为 android:onclick, 可用于直接在视图的活动中处理点击 无需实现任何接口。 如果需要,您可以轻松地将一种侦听器实现与另一种交换。 OnClickListener 使您能够将点击事件的操作/行为与触发事件的视图分开。虽然对于简单的情况这没什么大不了的,但对于复杂的事件处理,这可能意味着代码的可读性和可维护性更好 由于 OnClickListener 是一个接口,因此实现它的类可以灵活地确定处理事件所需的实例变量和方法。同样,这在简单的情况下没什么大不了的,但对于复杂的情况,我们不希望将与事件处理相关的变量/方法与触发事件的 View 的代码混为一谈。 在 XML 布局中具有函数绑定的 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_
    android:layout_
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

性能:

两者的性能相同。 Xml 在编译时被预先解析为二进制代码。所以在 Xml 中没有开销。

限制:

android:onClick 适用于 API 级别 4 及以上,因此如果您的目标是

【讨论】:

` Xml 在编译时被预解析成二进制代码` 这个语句到底是什么意思?由于我看到了一个在其清单文件中包含 android:onClick 的 apk 的 dexcode,但我没有找到任何明确设置侦听器的代码 很棒的解释。 +1 其实在XML中有一些开销。第一次单击该按钮时,reflection is used to determine the method that should be invoked。然而,这对于大多数用例来说可能是微不足道的(过早的优化是万恶之源)。【参考方案2】:

我很震惊没有人谈论这个,但要小心,虽然android:onClick XML 似乎是一种处理点击的便捷方式,但setOnClickListener 实现除了添加onClickListener 之外还做了一些额外的事情。事实上,它把视图属性clickable 设置为true。

虽然这在大多数 Android 实现中可能不是问题,但根据手机构造函数,按钮始终默认为 clickable = true,但某些手机型号上的其他构造函数可能在非按钮视图上具有默认可点击 = false。

所以设置 XML 是不够的,你必须一直考虑在非按钮上添加 android:clickable="true",如果你有一个默认为 clickable = true 的设备,你甚至忘记放置这个 XML 属性,您不会在运行时注意到问题,但会在市场反馈到您的客户手中时获得反馈!

此外,我们永远无法确定 proguard 将如何混淆和重命名 XML 属性和类方法,因此并非 100% 安全,他们永远不会有错误。

因此,如果您不想遇到麻烦并且从不考虑它,最好使用 setOnClickListener 或带有注释 @OnClick(R.id.button) 的 ButterKnife 之类的库

【讨论】:

在使用android:onClick时,你有没有经历过(或在某处看到过)由于混淆而出现的bug? 谢谢您,先生!你的回答很有帮助!【参考方案3】:

简单地说:

如果您有 android:onClick = "someMethod" 在 xml 中,它会在您的 Activity 类中查找 public void someMethodOnClickListener您的活动中被调用,它与某个特定的View 相关联。例如someButton.setOnClickListener,在下面的代码中说明了按下someButton 时必须执行的操作。

希望对你有帮助:)

【讨论】:

【参考方案4】:

如前所述:它们都是添加逻辑以响应事件(在本例中为“点击”事件)的一种方式。

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

【讨论】:

同意,除非它是一个具有一些简单行为的非常小的应用程序,否则您的所有执行代码都应该保持独立且井井有条,最好使用单独的方法【参考方案5】:

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

当您使用onClick 属性定义侦听器时,视图仅在其宿主活动中查找具有该名称的方法。以编程方式设置OnClickListener 允许您从其主机活动以外的其他位置控制按钮的行为。当我们使用Fragments 时,这将变得非常重要,它们基本上是迷你活动,允许您构建具有自己生命周期的可重用视图集合,然后可以将其组装成活动。 Fragments 总是需要使用OnClickListeners 来控制它们的按钮,因为它们不是Activity,并且不会搜索onClick 中定义的监听器。

【讨论】:

【参考方案6】:

如果你有几个按钮只使用一种方法,我建议在 java 中进行。但是,如果您有一个具有一种特定方法的按钮,那么 XML 中的 onClick 会更好。

【讨论】:

【参考方案7】:

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

【讨论】:

我很少看到其他人实现 android:onClick 的代码,当您查看其他人的代码时,这是最令人困惑的。因为它没有 setOnClickListener 的所有可能性,在我看来几乎每个人都只使用 setOnClickListener【参考方案8】:

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

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

OnClickListner:它可能是一个更广泛的选择,可以在各种代码中实现。

例如,当您输入 url “ymail.com”时,雅虎会从您的浏览器中找到您的用户名和密码,并启用点击状态按钮来打开您的邮件。这个动作应该只在 onClickListener 中实现。

这是我的主意!

【讨论】:

这很有趣,但远不止这些;你的应该是评论。

以上是关于XML 中的 Android onClick 与 OnClickListener的主要内容,如果未能解决你的问题,请参考以下文章

android:onClick XML 属性与 setOnClickListener 究竟有何不同?

无法使用数据绑定Android与ViewModel中的XML通信

如何处理片段中的onClick [重复]

Android 应用程序崩溃(片段和 xml onclick)

Android Proguard - 如何保持仅从 XML 布局引用的 onClick 处理程序

Android Studio的Button控件的onClick属性setOnClickListener函数与OnClickListener接口用法