Android 数据绑定库 vs Kotlin Android 扩展

Posted

技术标签:

【中文标题】Android 数据绑定库 vs Kotlin Android 扩展【英文标题】:Android Data Binding Library vs Kotlin Android Extensions 【发布时间】:2018-10-17 23:03:41 【问题描述】:

我正在阅读有关 MVVM 架构如何工作以及如何使用 android 数据绑定库帮助的信息。

总的来说,我理解 Android 数据绑定在 UI 层和包含要显示的信息的底层数据模型之间创建了一个链接。

Kotlin Android Extensions 是另一个 Kotlin 插件,可让您从活动、片段和视图中恢复视图。该插件将生成一些额外的代码,允许您访问 XML 布局中的视图,就像它们是具有您在布局定义中使用的 id 名称的属性一样。

使用 Android Data Binding Library 和 Kotlin Android Extensions 有什么区别?它们是出于不同的目的吗?它们以什么方式相互补充?

感谢您的回答。

【问题讨论】:

关于这方面的文章非常好:medium.com/google-developer-experts/… 【参考方案1】:

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

但它们还可以做更多的事情,可以相互补充。 详细地说,使用 Android 数据绑定库,您可以在 xml 文件中“设置”模型,然后可以直接利用这些模型为布局中的视图设置值。 See <data> 标签如何与数据绑定库一起使用。

Kotlin android 扩展不提供此功能。 同时,Kotlin android 扩展提供了一些惊人的功能,例如@parcelize 注解,使类可以打包,几乎不需要样板代码等。

总而言之,虽然它们都消除了findViewById 的使用,但它们也有自己的特点,可以很好地相互补充。

【讨论】:

在生成代码或构建时间的情况下您更喜欢哪一个? 另外,我刚刚意识到并想补充一点,KTX 似乎没有提供可在代码中使用的具体布局绑定类。它仅提供对布局类中指定的 ID 作为字段变量的引用,可以在代码中使用,但不能在整个布局本身中使用。【参考方案2】:

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

来自official documentation:

数据绑定库在绑定中创建一个不可变字段 布局中具有 ID 的每个视图的类... 库提取 视图包括视图层次结构中的 ID 一次传递。 这种机制可以比调用 findViewById() 方法更快 布局中的每个视图。

所以数据绑定不会在视图上一一调用 findViewById。另一方面,Kotlin 的合成类仍然在底层视图上调用 findViewById,但它只为每个视图调用一次,并为下一次调用缓存视图引用。 (这里有一个article 关于它)

此外,数据绑定提供的不仅仅是视图缓存。您可以使用数据标签将数据传递给绑定实现并在您的 xml 中声明它们,而不是以编程方式设置它们。通过这种方式,您可以摆脱用于填充数据的样板代码,例如“setText”、“setImageResource”等。您可以使用数据绑定从 xml 设置事件侦听器。您还可以使用自定义绑定适配器提供自己的属性。当使用它的全部功能时,它可以显着减少您的 Java/Kotlin 代码。

编辑: Google Android 团队似乎建议反对使用 kotlin 合成属性。 This article 总结了围绕这个问题的讨论。您可以在 Google 准备的新 Udacity course 中看到他们使用数据绑定作为推荐做法。

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

【讨论】:

【参考方案3】:

我强烈不同意上述观点。也许是因为我讨厌用 XML 编写逻辑。所以两个 cmets 都提到了在 Kotlin Android Extensions (KTX) 中找不到的 <data> 标签的使用。使用 kotlin 和 KTX,你可以做得比数据标签更好。

假设我们有

data class Person(val name:String, 
                   val phone:String,
                   val isMale:Boolean,
                   val isMarried:Boolean)

在activity或者fragment中,我们可以做

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 Extensions 工作得更好。我喜欢我的代码干净。您仍然可以同时使用这两种方法,您可以自行决定。

【讨论】:

你不必像数据绑定那样做。事实上,你不应该那样做。不建议在 xml 中使用复杂的三元运算符,因为您提到的可读性以及 xml 代码不可测试。所以你可以对数据绑定做些什么,就是使用一个辅助方法,它接受一个人作为参数并返回你需要的文本。 既然我可以使用 ktx 和 kotlin 轻松做到这一点,为什么还要使用数据绑定 + 辅助类!? 我只是想澄清一下,您不必在数据绑定中使用“丑陋”或不可读的三元运算符。当然,如果感觉像“打扰”,您不必打扰。我想这是关于某人习惯的事情。对我来说,数据绑定意味着我的活动和片段中的代码要少得多。 尽管有一些反对 Kotlin 合成属性的论据。 Google 团队建议改为使用数据绑定。本文总结了有关该问题的讨论:proandroiddev.com/… 但是,您仍然没有义务遵循 Google 的建议。最终由你决定。 我看了一篇文章,发现在 RecyclerView onBindView 中不建议使用 kotlin android 扩展,因为它在后台调用 findViewById。

以上是关于Android 数据绑定库 vs Kotlin Android 扩展的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin-android:未解决的参考数据绑定

Xamarin 是不是支持 Xamarin Android 绑定库中的 Kotlin 协程?

Android数据绑定:如何获取kotlin枚举类的字段值?

使用 kotlin 的 recyclerview 中的数据绑定导致问题

使用 Android 数据绑定时禁用 Kotlin 合成绑定

DataBinding——使用Kotlin 委托优化