竟然如此简单,DataBinding 和 ViewBinding
- 如果评论区没有及时回复,欢迎来公众号:ByteCode 咨询
- 公众号:ByteCode。致力于分享最新技术原创文章,涉及 Kotlin、Jetpack、算法、译文、系统源码相关的文章
前言
首先祝小伙伴们新年快乐,2020 一个不平凡的一年,2021 是你我新的起点。
2021 新签名:代码不止,文章不停。
2021 第一篇文章是对 2020 年末最后一篇文章 Kotlin 插件的落幕,ViewBinding 的崛起 的一个补充。
在之前的文章 Kotlin 插件的落幕,ViewBinding 的崛起 中介绍了 Google 为什么不建议在项目中使用 Kotlin 合成方法(Synthetic 视图), Google 建议使用 ViewBinding 替换 Kotlin 合成方法,那么 ViewBinding 和 DataBinding 都有什么区别。
ViewBinding:
- 仅仅支持绑定 View
- 不需要在布局文件中添加 layout 标签
- 需要在模块级
build.gradle
文件中添加viewBinding = true
即可使用 - 效率高于 DataBinding,因为避免了与数据绑定相关的开销和性能问题
- 相比于
kotlin-android-extensions
插件避免了空异常
DataBinding:
- 包含了 ViewBinding 所有的功能
- 需要在模块级
build.gradle
文件内添加dataBinding = true
并且需要在布局文件中添加 layout 标签才可以使用 - 支持 data 和 view 双向绑定
- 效率低于 ViewBinding,因为注释处理器会影响数据绑定的构建时间。
ViewBinding 可以实现的, DataBinding 都可以实现,但是 DataBinding 的性能低于 ViewBinding,DataBinding 和 ViewBinding 会为每个 XML 文件生成绑定类。
R.layout.activity_main -> ActivityMainBinding |
在 Kotlin 插件的落幕,ViewBinding 的崛起 文章中同时也分析了 Kotlin 合成方法所带来的问题。即使 Kotlin 合成方法有很多问题,但是还有小伙伴愿意使用。
ViewBinding 和 DataBinding 为我们解决了这么多问题,但是为什么很多小伙伴们不愿意使用 ViewBinding 和 DataBinding,今天我们从使用的角度来分析。
ViewBinding 和 DataBinding
我大概汇总了 ViewBinding 和 DataBinding 在不同场景的所有用法,我们来看一下在项目中如何使用。
基本配置
从 Android Studio 3.6
版本开始,就内置在 Gradle 插件中了,不需要添加任何额外的库来使用它们,但是在 Android Studio 3.6
和 Android Studio 4.0
中使用方式不一样。
// Android Studio 3.6 |
ViewBinding 的使用
因为涉及到的场景比较多,为了减少篇幅,我只列出来核心部分,如果之前从来没有用过,这里只需要知道 ViewBinding 的门槛比 Kotlin 合成方法要高即可。
不想为某个布局生成 binding 类,将下面属性添加到布局文件的根视图中
<LinearLayout tools:viewBindingIgnore="true" > |
在 Activity 中使用
override fun onCreate(savedInstanceState: Bundle?) { |
在 Fragment 中使用
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { |
在 Adapter 中的使用
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { |
在 Dialog 中使用
override fun onCreate(savedInstanceState: Bundle?) { |
include 标签的使用
include
标签不带 merge
标签,需要给 include
标签添加 id, 直接使用 id 即可,用法如下所示。
<include |
include
标签带 merge
标签,注意这里和 DataBinding 用法不一样,给 include
标签添加 id,在 DataBinding 中可以直接使用 id,ViewBinding 则不行,ViewBinding 的用法如下所示。
<include layout="@layout/layout_merge_item" /> |
ViewStub 标签的使用
根据实践证明,截止到这篇文章发布时,在 Android Studio 4.2.0 bata 2
中,无法直接在 ViewBinding 布局中使用 ViewStub
标签,仅仅只能在 DataBinding 布局(带 layout
标签)中使用,详见 issue
因为没有找到比较权威的资料证明,这里建议小伙们直接在项目 Binding 中进行尝试,如果有其他在 ViewBinding 布局中的实现方式,欢迎留言告知我
DataBinding 的使用
因为涉及到的场景比较多,为了减少篇幅,我只列出来核心部分,如果之前从来没有用过,这里只需要知道 DataBinding 的门槛比 Kotlin 合成方法要高即可。
需要给布局文件添加 layout 标签
<layout xmlns:android="http://schemas.android.com/apk/res/android"> |
在 Activity 中使用
override fun onCreate(savedInstanceState: Bundle?) { |
在 Fragment 中使用
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { |
在 Adapter 中的使用
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { |
在 Dialog 中使用
override fun onCreate(savedInstanceState: Bundle?) { |
include 标签的使用
include
标签不带 merge
标签,需要给 include
标签添加 id, 直接使用 id 即可。
<include |
include
标签带 merge
标签,注意这里和 ViewBinding 用法不一样,给 include
标签添加 id,在 DataBinding 中可以直接使用,在 ViewBinding 中则不行。
<include |
ViewStub 标签的使用
给 ViewStub
标签添加 id, 在 DataBinding 中可以直接使用 id 即可。
<ViewStub |
val binding: ActivityViewBindBinding by viewbind()
|
val binding: ActivityDataBindBinding by databind(R.layout.activity_data_bind)
或者
val binding: ActivityDataBindBinding by databind()
|
dependencies {
implementation ‘com.hi-dhl:binding:1.0.7’
}
|
class MainActivity : AppCompatActivity() {
// DataBinding
val binding: ActivityMainBinding by databind(R.layout.activity_main)
// ViewBinding
val binding: ActivityMainBinding by viewbind()
}
|
class FragmentNav1 : Fragment(R.layout.fragment_main) {
// DataBinding
val binding: FragmentMainBinding by databind()
// ViewBinding
val binding: FragmentMainBinding by viewbind()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return binding.root
}
}
|
class FragmentNav1 : Fragment(R.layout.fragment_main) {
// DataBinding
val binding: FragmentMainBinding by databind()
// ViewBinding
val binding: FragmentMainBinding by viewbind()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply { textView.setText("Binding") }
}
}
|
class AppDialog(context: Context) : Dialog(context, R.style.AppDialog) {
// DataBinding
val binding: DialogAppBinding by databind(R.layout.dialog_data_binding)
// ViewBinding
val binding: DialogAppBinding by viewbind()
}
|
class AppDialog(context: Context,lifecycle: Lifecycle) : Dialog(context, R.style.AppDialog) {
// DataBinding 监听生命周期
val binding: DialogAppBinding by databind(R.layout.dialog_data_binding, lifecycle)
// ViewBinding 监听生命周期
val binding: DialogAppBinding by viewbind(lifecycle)
}
|
class ProductViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// DataBinding
val binding: RecycleItemProductBinding by databind()
// ViewBinding
val binding: RecycleItemProductHeaderBinding by viewbind()
}
|
val binding: ActivityDataBindBinding by databind(R.layout.activity_data_bind) {
val account = Account()
account.name = “test”
this.account = account
}
上面只是常见的几种用法,当然还有更多实战案例(`include` 、 `merge` 、 `ViewStub` 、 `Navigation` 、 数据双向绑定 等等)已经上传到 GitHub 欢迎前去仓库 [Binding](https://github.com/hi-dhl/Binding) 查看。
GitHub 仓库: [https://github.com/hi-dhl/Binding](https://github.com/hi-dhl/Binding)
这篇文章可以理解为对之前的文章 [Kotlin 插件的落幕,ViewBinding 的崛起](https://juejin.cn/post/6905942568467759111) 的一个补充,从使用的角度分析了 DataBinding 和 ViewBinding 不同之处,同时也介绍了如何用更简单的方式实现 DataBinding 和 ViewBinding。
- 本文作者:hi-dhl
- 本文标题:竟然如此简单,DataBinding 和 ViewBinding
- 本文链接:https://hi-dhl.com/2021/01/26/kotlin/07-use-viewbinding/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 hi-dhl