ViewBinding 与 Kotlin Android 具有合成视图的扩展

ViewBinding vs Kotlin Android Extensions with synthetic views

新的ViewBinding compare with the Kotlin Android Extensions如何与合成视图绑定?

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

新的 ViewBinding 是否更高效,因为它预先生成了绑定 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它:return binding.root
  3. 通过使用其 ID 绑定在代码中引用视图 binding.textView.text = "Hello, world!"

类型安全

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


空安全

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

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


应用布局更改

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


布局使用不正确

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


KAE 与 ViewBinding 的总结

  • 类型安全 - 绘制。
  • 空安全 - 平局。
  • 样板代码 - KAE 获胜。来自 Kotlin Android 扩展 documentation:

The Kotlin Android Extensions plugin allows us to obtain the same experience we have with some of these libraries, without having to add any extra code.

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

我认为关于 ViewBinding 替代 KAE 存在很大的误解。人们听到大关键词并在没有事先验证的情况下重复它们。当然,ViewBinding 是目前 Java 开发的最佳选择(替代 ButterKnife),但与 Kotlin 中的 KAE(参见不正确的布局用法部分)。

旁注: 我确定使用 DataBinding 的人会喜欢 ViewBinding :)

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

我们创建两个名为 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>

现在,如果你这样写 activity:

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!"
    }
}

您的代码将无任何错误地编译,但您的应用程序将在运行时崩溃。因为 message_other id 的视图在 activity_main 中不存在,编译器没有检查这个。但是如果你像这样使用 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 不再是推荐的做法,google 在一个提交消息中说“Reddit 线程之一

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

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

"Now question comes, which one we have to take it in consideration."

根据google(View binding、ButterKnife、Kotlin synthetics),这些库被许多应用成功使用并解决了同样的问题。

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

附上参考图片以快速清除事物。

但是,如果您想进入部门,可以按照下面的说明进行操作 link。 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