新的ViewBinding与带有合成视图绑定的Kotlin Android 扩展相比如何?
除了新的 ViewBindings 提供的 NullSafety 和 TypeSafety 之外,我们为什么要考虑放弃 Kotlin 在 Views 上使用合成绑定的方式?
新的 ViewBinding 是否更高效,因为它预先生成了 Binding 类?
新的ViewBinding与带有合成视图绑定的Kotlin Android 扩展相比如何?
除了新的 ViewBindings 提供的 NullSafety 和 TypeSafety 之外,我们为什么要考虑放弃 Kotlin 在 Views 上使用合成绑定的方式?
新的 ViewBinding 是否更高效,因为它预先生成了 Binding 类?
让我们回顾一下两者。
import kotlinx.android.synthetic.main.<layout>.*
textView.text = "Hello, world!"
. 这些扩展适用于Activities
:Fragments
和Views
。private lateinit var binding
YourClassBinding
binding = YourClassBinding.inflate(layoutInflater)
在Activity
'sonCreate
和 call中膨胀你的绑定,或者在'ssetContentView(binding.root)
中膨胀它然后返回它:Fragment
onCreateView
return binding.root
binding.textView.text = "Hello, world!"
Kotlin Android Extensions和ViewBinding在定义上是类型安全的,因为引用的视图已经被转换为适当的类型。
Kotlin Android Extensions和ViewBinding都是 null 安全的。ViewBinding 在这里没有任何优势。在KAE的情况下,如果视图仅存在于某些布局配置中,IDE 会为您指出:
因此,您只需将其视为 Kotlin 中的任何其他可为空的类型,错误就会消失:
在Kotlin Android Extensions的情况下,布局更改会立即转化为合成扩展的生成,因此您可以立即使用它们。在ViewBinding的情况下,您必须构建您的项目
在Kotlin Android Extensions的情况下,可能会导入不正确的布局合成扩展,从而导致NullPointerException
. 这同样适用于ViewBinding,因为我们可以导入错误Binding
的类。Activity
虽然,错误的导入比错误的类名更容易被忽略,特别是如果布局文件以/ Fragment
/命名View
,所以ViewBinding在这里占上风。
Kotlin Android Extensions 插件允许我们获得与其中一些库相同的体验,而无需添加任何额外代码。
我认为ViewBinding替代KAE存在很大的误解。人们听到大关键字并重复它们而无需事先验证。当然,ViewBinding是目前 Java 开发的最佳选择(替代ButterKnife ),但在 Kotlin 中与KAE相比没有或几乎没有优势(请参阅不正确的布局使用部分)。
旁注: 我相信 DataBinding 的人会喜欢 ViewBinding :)
ViewBinding
解决了最大的问题kotlinx.android.synthetic
。在synthetic
绑定中,如果您将内容视图设置为布局,然后键入仅存在于不同布局中的 id,IDE 允许您自动完成并添加新的导入语句。除非开发人员专门检查以确保他们的导入语句只导入正确的视图,否则没有安全的方法来验证这不会导致运行时问题。但是ViewBinding
你应该使用你的layout
绑定对象来访问它的视图,这样你就永远不会调用不同布局中的视图,如果你想这样做,你会得到一个编译错误而不是运行时错误。这是一个例子。
我们创建了两个布局activity_main
,activity_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!"
}
}
您的代码将无任何错误地编译,但您的应用程序将在运行时崩溃。因为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
在最后一行显示错误。
Kotlin Android Extensions 已在 Kotlin 1.4.20 中弃用,因此我建议使用 ViewBinding。
kotlinx.android.synthetic 不再是推荐的做法,谷歌在一个提交消息“Reddit 线程之一”中说
https://android-review.googlesource.com/c/platform/frameworks/support/+/882241 “
Synthetics不是由 google 开发的,它是 JetBrains 制作的 kotlin android 扩展的一部分,并且逐渐 google android 开发人员开始在他们的演示和源代码中用 ViewBindins 替换 Synthetics。
“现在问题来了,我们必须考虑哪一个。”
根据 google(视图绑定、ButterKnife、Kotlin 合成)的说法,这些库已被许多应用程序成功使用并解决了相同的问题。
但是对于大多数应用程序,谷歌建议尝试视图绑定而不是这些库,因为视图绑定提供了更安全、更简洁的视图查找。
但是,如果您想进入部门,可以按照以下链接进行操作。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc