繁体   English   中英

ViewBinding 与 Kotlin Android 扩展与合成视图

[英]ViewBinding vs Kotlin Android Extensions with synthetic views

新的ViewBinding与具有合成视图绑定的Kotlin Android 扩展相比如何?

除了新的 ViewBindings 提供的 NullSafety 和 TypeSafety 之外,我们为什么要考虑放弃 Kotlin 在 Views 上使用合成绑定的方式?

新的 ViewBinding 是否更高效,因为它预先生成了 Binding class?

让我们回顾一下两者。


配置

Kotlin Android 扩展

  1. 导入适当的布局合成扩展: import kotlinx.android.synthetic.main.<layout>.*
  2. 通过 id 引用代码中的视图: textView.text = "Hello, world!" . 这些扩展适用于: ActivitiesFragmentsViews

视图绑定

  1. 在 class 中创建绑定引用: private lateinit var binding YourClassBinding
  2. ActivityonCreate中膨胀你的绑定binding = YourClassBinding.inflate(layoutInflater)并调用setContentView(binding.root) ,或者在FragmentonCreateView中膨胀它然后返回它: return binding.root
  3. 通过使用其 id 绑定来引用代码中的视图binding.textView.text = "Hello, world!"

类型安全

Kotlin Android 根据定义,扩展ViewBinding是类型安全的,因为引用的视图已经转换为适当的类型。


Null安全

Kotlin Android 扩展ViewBinding都是 null 安全的。 ViewBinding 在这里没有任何优势 KAE的情况下,如果视图仅存在于某些布局配置中,IDE 会为您指出:

在此处输入图像描述

因此,您只需将其视为 Kotlin 中的任何其他可为空的类型,错误就会消失:

在此处输入图像描述


应用布局更改

Kotlin Android Extensions的情况下,布局更改会立即转化为合成扩展的生成,因此您可以立即使用它们。 ViewBinding的情况下,您必须构建您的项目


布局使用不正确

Kotlin Android Extensions的情况下,可能会导入不正确的布局合成扩展,从而导致NullPointerException 这同样适用于ViewBinding ,因为我们可以导入错误的Binding class。 虽然,与不正确的 class 名称相比,更可能忽略不正确的导入,特别是如果布局文件以Activity / Fragment / View命名,因此ViewBinding在这里占据上风。


KAE 与 ViewBinding 的总结

  • 类型安全- 绘制。
  • Null 安全- 绘制。
  • 样板代码- KAE获胜。 来自 Kotlin Android 扩展文档

Kotlin Android Extensions 插件允许我们获得与其中一些库相同的体验,而无需添加任何额外的代码。

  • 应用布局更改- KAE获胜。 ViewBinding相比,更改是即时的。
  • 布局使用不正确- ViewBinding获胜

我认为ViewBinding替代KAE存在很大的误解。 人们听到大关键字并重复它们而无需事先验证。 当然, ViewBinding是目前 Java 开发的最佳选择(替代ButterKnife ),但在 Kotlin 中与KAE相比没有或几乎没有优势(请参阅不正确的布局使用部分)。

旁注:我确信 DataBinding 的人会喜欢 ViewBinding :)

ViewBinding解决了kotlinx.android.synthetic的最大问题。 synthetic绑定中,如果您将内容视图设置为布局,然后键入仅存在于不同布局中的 id,IDE 可让您自动完成并添加新的导入语句。 除非开发人员专门检查以确保他们的导入语句只导入正确的视图,否则没有安全的方法来验证这不会导致运行时问题。 但是在ViewBinding中,您应该使用layout绑定 object 来访问其视图,因此您永远不会调用不同布局中的视图,如果您想这样做,您将收到编译错误而不是运行时错误。 这是一个例子。

我们创建了两个布局,分别称为activity_mainactivity_other ,如下所示:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
        android:id="@+id/message_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

activity_other.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"
                >

    <TextView
        android:id="@+id/message_other"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

现在,如果您像这样编写活动:

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_other.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Application will crash because "message_other" doesn't exist in "activity_main"
        message_other.text = "Hello!"
    }
}

您的代码将无任何错误地编译,但您的应用程序将在运行时崩溃。 因为在activity_main中不存在message_other id 的视图,并且编译器没有检查这一点。 但是如果你像这样使用ViewBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //This code will never compile and the IDE shows you an error
        binding.message_other.text = "Hello!"
    }
}

您的代码将永远无法编译, Android Studio在最后一行显示错误。

kotlinx.android.synthetic 不再是推荐的做法,谷歌在一个提交消息“Reddit 线程之一”中说

https://android-review.googlesource.com/c/platform/frameworks/support/+/882241

Synthetics不是由 google 开发的,它是 kotlin android 扩展的一部分,由 JetBrains 制作并逐渐 google android 开发人员开始在他们的演示中替换 Synthetics 并绑定源代码。

“现在问题来了,我们必须考虑哪一个。”

根据谷歌(视图绑定,ButterKnife,Kotlin 合成)这些库被许多应用程序成功使用并解决了同样的问题。

但是对于大多数应用程序,谷歌建议尝试视图绑定而不是这些库,因为视图绑定提供了更安全、更简洁的视图查找。

附上参考图像以快速清除事物。 在此处输入图像描述

但是,如果您想深入了解 go,您可以点击以下链接。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

Kotlin Android 扩展将被 Kotlin 1.4.20 弃用,所以我建议使用 ViewBinding。

https://proandroiddev.com/migrating-the-deprecated-kotlin-android-extensions-compiler-plugin-to-viewbinding-d234c691dec7

三是这个家伙的关于性能与数据绑定和视图绑定基于数据绑定的问题,所以,这可以帮助你。

暂无
暂无

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

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