视图绑定(ViewBinding )与数据绑定(Databinding)
什么是ViewBinding
viewbinding是android jetpack的一个特性,通过viewbinding功能,您可以更轻松地编写可与视图交互的代码。在模块中启用viewbinding之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
用法
如何配置Viewbinding
在每一个模块中的build.gradle中进行如下配置
android {
...
viewBinding {
enabled = true
}
}
为某个模块启用视图绑定功能后,系统会为该模块中包含的每个 XML 布局文件生成一个绑定类。每个绑定类均包含对根视图以及具有 ID 的所有视图的引用。系统会通过以下方式生成绑定类的名称:将 XML 文件的名称转换为驼峰式大小写,并在末尾添加“Binding”一词。
viewbinding在Activity中使用
例子:假设有一个布局是 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".MainActivity">
<Button
android:text="这是按钮"
android:id="@+id/test_view_binding"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
在Activity中,viewBinding的用法如下:
class MainActivity : Activity() {
//首先声明变量
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//再通过生成的binding去加载该布局
binding = ActivityMainBinding.inflate(layoutInflater)
//调用Binding类的getRoot()函数可以得到activity_main.xml中根元素的实例
val view = binding.root
//将根视图传递到 setContentView(),使其成为屏幕上的活动视图
setContentView(view)
//使用binding实例获取到控件
binding.testViewBinding.text = "button"
}
}
viewbinding在Fragment中使用
在fragment使用viewBinding,以下是官网的一个例子
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
这里做一下解释为什么这里实现起来稍微有点奇怪。首先kotlin是有空安全的属性的,所以直接使用_binding这个属性是不可以的。那为什么不使用和activity中的那种通过声明lateinit变量的方式来实现呢?来看看上述官网的例子里面的一个注释 ,这句话翻译过来就是这个binding变量只有在onCreateView与onDestroyView才是可用的。因为我们fragment的生命周期和activity的不同,fragment 可以超出其视图的生命周期,如果不将这里置为空,有可能引起内存泄漏。
viewbinding含有include标签中布局的使用
title_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="include"
android:id="@+id/test_include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"