文章目录

  • viewBinding
  • 添加支持
  • 页面使用
  • 绑定类与id
  • getRoot
  • activity使用
  • fragment使用
  • 优势
  • 与 findViewById 的区别
  • 与数据绑定的对比




视图绑定主要是替代findViewById功能的,使用视图绑定可以减少依赖和重复代码

viewBinding

在AndroidStudio3.6以上使用

使用方式:

添加支持

在对应的Build.gradle中添加viewBinding:true支持

android {
        ...
        viewBinding {
            enabled = true
        }
	}

页面使用

在页面中使用:比如我们声明了一个xml文件名称为aaa_bbb.xml,那么使用viewBinding的情况下,会生成一个名为AaaBbbBinding的绑定类对象,名称与布局文件名称是对应的,是驼峰法命名

如果不想在某个布局中使用,可以使用忽略:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

绑定类与id

这个类中的字段对应的是xml文件中的id的名称,如果没有id,那么类中就没有对应的字段。比如官方的例子中。假设一个布局文件为result_profile.xml:

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

那么生成的绑定类的名称就为 ResultProfileBinding,此类具有两个字段:一个是名为 name 的 TextView,另一个是名为 button 的 Button。该布局中的 ImageView 没有 ID,因此绑定类中不存在对它的引用。

getRoot

每个绑定类提供一个getRoot方法,用于为相应布局文件的根视图提供直接引用。上面的示例中,ResultProfileBinding 类中的 getRoot() 方法会返回 LinearLayout 根视图。

activity使用

在Activity中使用,基本流程就是生成类对象,使用getRoot方法,引用id字段
官方的例子:

在onCreate方法中:

  1. 调用绑定类的静态inflate方法生成绑定类对象
  2. 通过getRoot方法得到对根视图的引用
  3. 将根视图传入setContentView()中在屏幕显示
  4. 通过绑定类对象进行字段对应的控件操作
private lateinit var binding: ResultProfileBinding

 override fun onCreate(savedInstanceState: Bundle) {
     super.onCreate(savedInstanceState)
     binding = ResultProfileBinding.inflate(layoutInflater)
     val view = binding.root
     setContentView(view)
 }

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

fragment使用

在fragment中使用和activity中的相似,activity中是在onCreate中,Fragment就是在onCreateView中

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(......): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

使用方式和activity中一样

优势

与 findViewById 的区别

与使用 findViewById 相比,视图绑定具有一些很显著的优点:

Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。此外,如果视图仅出现在布局的某些配置中,则绑定类中包含其引用的字段会使用 @Nullable 标记。

类型安全:每个绑定类中的字段均具有与它们在 XML 文件中引用的视图相匹配的类型。这意味着不存在发生类转换异常的风险。

这些差异意味着布局和代码之间的不兼容将会导致构建在编译时(而非运行时)失败。

与数据绑定的对比

视图绑定和数据绑定均会生成可用于直接引用视图的绑定类。但是,视图绑定旨在处理更简单的用例,与数据绑定相比,具有以下优势:

更快的编译速度:视图绑定不需要处理注释,因此编译时间更短。
易于使用:视图绑定不需要特别标记的 XML 布局文件,因此在应用中采用速度更快。在模块中启用视图绑定后,它会自动应用于该模块的所有布局。
反过来,与数据绑定相比,视图绑定也具有以下限制:

视图绑定不支持布局变量或布局表达式,因此不能用于直接在 XML 布局文件中声明动态界面内容。
视图绑定不支持双向数据绑定。

考虑到这些因素,在某些情况下,最好在项目中同时使用视图绑定和数据绑定。您可以在需要高级功能的布局中使用数据绑定,而在不需要高级功能的布局中使用视图绑定。