Android数据绑定库与Kotlin Android扩展之间的区别

50
我正在了解MVVM架构以及如何使用Android数据绑定库。从非常普遍的角度来看,我理解Android数据绑定创建了一个链接,在UI层和持有显示信息的底层数据模型之间。另外,Kotlin Android Extensions是另一个Kotlin插件,它允许你从Activities、Fragments和Views中恢复视图,该插件会生成一些额外的代码,使你能够访问XML布局中的视图,就像它们是布局定义中使用的id属性的名称一样。
那么,使用Android数据绑定库和Kotlin Android Extensions之间有什么区别?它们是否用于不同的目的?它们如何相互补充?
谢谢您的回答。

关于这个的真正好的文章:https://medium.com/google-developer-experts/exploring-view-binding-on-android-44e57ba11635 - SebastienRieu
3个回答

31

Kotlin Android Extensions 不仅代表视图绑定。它还包含其他功能。但我想你在谈论 Kotlin Android Extensions 的视图绑定/缓存功能,并想知道我们是否仍然需要数据绑定,因为我们已经通过 Kotlin 的合成属性摆脱了 findViewById 调用。这是我问自己的问题,我的结论是,是的,仍然值得使用数据绑定。

根据官方文档

数据绑定库会为布局中每个具有 ID 的视图创建一个不可变字段...该库会在单次遍历中从视图层次结构中提取包括 ID 在内的视图。这种机制可能比对布局中每个视图调用 findViewById() 方法要快。

因此,数据绑定不会逐个调用视图上的findViewById。另一方面,Kotlin 的合成类在幕后仍会在视图上调用 findViewById,但仅对每个视图调用一次,并缓存视图引用以供下一次调用。(这是一篇关于此的文章

此外,数据绑定不仅可以用于视图缓存。您可以使用数据标记将数据传递给绑定实现并在xml中声明它们,而不是通过编程方式设置它们。这样,您就可以摆脱用于填充数据的样板代码,例如 "setText"、 "setImageResource" 等。您可以使用数据绑定从xml设置事件监听器。您还可以使用自定义绑定适配器来创建自己的属性。当充分利用其功能时,它可以显著减少 Java/Kotlin 代码量。
编辑:Google Android 团队似乎建议不要使用 Kotlin 合成属性。 此文章 总结了围绕此问题的讨论。在 Google 准备的新Udacity 课程中可以看到,他们使用数据绑定作为建议的做法。

编辑2:如果您不喜欢“在xml中加入业务逻辑”的想法,如果您对设置或从xml获取数据不感兴趣,如果您只是想以安全有效的方式避免使用findViewByIds,则可以选择使用ViewDataBinding库。它是数据绑定库的简化版本。它不允许您从xml设置数据,但可以以安全有效的方式绑定视图。


31

Kotlin Android Extensions和Android Data Binding Library都有助于消除对findViewById的使用。

但是它们都有更多的功能,可以相互补充。具体来说,使用Android Data Binding库,您可以在xml文件中“设置”模型,然后直接利用这些模型为布局中的视图设置值。请参阅如何通过数据绑定库使用<data>标签。

Kotlin android extensions没有提供此功能。与此同时,Kotlin android extensions提供了一些令人惊叹的功能,例如@parcelize注释,使类可以轻松地进行序列化而无需编写样板代码等。

总之,虽然它们都消除了对findViewById的使用,但它们也拥有自己的特色功能,可以很好地相互补充。


5
在生成代码或构建时间中,你更喜欢哪一个? - Hemant Kaushik
另外,我刚意识到并想补充一点,KTX似乎没有提供可以在代码中使用的具体布局绑定类。它仅提供对布局类中指定的ID的引用作为字段变量,这些变量可以在代码中使用,但不包括整个布局本身。 - Saifur Rahman Mohsin

1
我强烈不同意上述观点。也许是因为我讨厌在XML中编写逻辑。因此,两个评论都提到了在Kotlin Android扩展(KTX)中找不到的<data>标签的使用。使用Kotlin和KTX,您可以比data标签做得更好。
假设我们有:
data class Person(val name:String, 
                   val phone:String,
                   val isMale:Boolean,
                   val isMarried:Boolean)

在活动或片段中,我们可以做以下操作:
fun updateView(data:Person){
    with(data){

     nameTextField.text = if(isMale){
                            "Mr. $name" 
                          } else {
                             if(isMarried){
                              "Mrs. $name"
                             }else{
                              "Miss $name"
                             }
                          }
     phoneTextField.text = phone
    }
 }

在数据绑定中,您需要执行以下操作: android:text='@{person.isMale ? "Mr."+user.name: ((user.isMarried ? "Mrs. " : "Miss. ") + user.name)}' KTX代码比使用数据绑定实现相同结果的代码更加简洁。当您需要条件设置视图数据的值时,数据绑定会变得很丑陋。因此,对我而言,Kotlin Android扩展效果更好。我喜欢我的代码整洁。您仍然可以使用两者,决定权在您手中。

5
使用DataBinding时,您不需要像这样做。事实上,您不应该这样做。在XML中使用复杂的三元运算符不推荐,因为它们不易读且XML代码不能进行测试。所以,您可以使用一个帮助方法来处理DataBinding,该方法将接受一个人类作为参数并返回所需的文本。请注意保持原意不变,使翻译更加通俗易懂。 - Oya Canli
既然我可以使用 ktx 和 kotlin 轻松地完成这个任务,为什么还要使用数据绑定+助手类呢!? - Manzur Alahi
2
我只想澄清一下,在数据绑定中,你不必使用“丑陋”或难读的三元运算符。当然,如果觉得“麻烦”,也没必要费心。我想这取决于个人习惯。对我来说,数据绑定意味着我的活动和片段中有显著减少的代码。 - Oya Canli
1
尽管有一些反对 Kotlin 的合成属性的观点,但 Google 团队建议使用数据绑定。该文章总结了该问题的讨论: https://proandroiddev.com/the-argument-over-kotlin-synthetics-735305dd4ed0 但是,你没有义务遵循 Google 的建议。最终决定取决于你。 - Oya Canli
我读了一篇文章,发现在RecyclerView的onBindView方法中不推荐使用Kotlin Android扩展,因为它在底层调用了findViewById。 - Astha Garg
除非你正在构建一个非常复杂的应用程序,否则Android提供的大多数功能都不是必需的。只需使用适合您的内容,并尽量不要过于复杂化。 - Manzur Alahi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接