前言

本章为 DataBinding 先做个铺垫,讲解下 ViewBinding
ViewBinding 主要是用来释放 findViewById 当我们在实际业务开发中如果不需要 DataBinding 的强大功能的时候(DataBinding 很重,layout 内部复杂,耗费性能),可以使用 ViewBinding;
基础使用
模块的 build.gradle 中,声明 closure
arduino
// 启用ViewBinding
viewBinding {
enabled true
}
和 DataBinding 的启用方式一样;
启用之后,我们就不需要 ButterKnife 以及 findViewById 这种方式了;
我们先来声明 xml 文件,取名叫 activity_main.xml
ini
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
代码很简单,就是界面上放了三个 TextView,然后,我们在 Activity 中通过 ViewBinding 将这 xml 和 Activity 关联起来;
当我们通过 studio 创建这个 xml 的时候,gradle 插件就帮我们生成了一个类,根据 activity_main 这个名字生成了一个 ActivityMainBinding 类;然后我们就可以在 Activity 中调用这个类来将 xml 和 Activity 绑定到一起;
scala
// ViewBinding背后不是用 APT 注解处理器 使用什么? 答:gradle插件
public class MainActivity extends AppCompatActivity {
ActivityMainBinding mainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mainBinding.getRoot());
mainBinding.tv1.setText("AAA");
mainBinding.tv2.setText("BNB");
mainBinding.tv3.setText("DDDD");
}
}
可以看到,ViewBinding 并不需要在 xml 中搞什么复杂的 layout 标签嵌套之类的;也不需要在 Activity 中声明 findViewById 了;
ViewBinding 背后不是用 APT 注解处理器;那么它使用的是什么?答:gradle插件;
通过 gradle 插件提升了编译速度,不像 DataBinding 那么耗费性能;
与 kotlin 绑定机制的差异
接下来讲一下两者的差异
kotlin 的绑定启用
arduino
plugins {
// 有绑定机制后,就不需要 findViewById gradle插件
id 'kotlin-android-extensions' // 启用 绑定机制
}
kotlin 的绑定也是在 build.gradle 中启用 kotlin 的一个 gradle 插件;
启用这个插件之后,Activity 中可以直接使用,但是这个必须在 kt 文件中,java 中是不好使的;
kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
// 核心逻辑
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 绑定机制的缺点
setContentView(R.layout.activity_main)
tv1.text = "AAA"
tv2.text = "BBB"
tv3.text = "CCC"
}
}
kotlin 的这个绑定机制有个缺陷,就是可以在当前的 Activity 中绑定任何 xml,但是,我们需要通过 setContentView 绑定 xml 和 Activity,如果在 Activity 中访问了其他 xml 中的元素,就会导致启动崩溃;
kotlin
// 绑定机制的缺点1
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.test.*
class MainActivity : AppCompatActivity() {
var vb: ActivityMainBinding ? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 绑定机制的缺点2
setContentView(R.layout.activity_main)
tv1.text = "AAA"
tv2.text = "BBB"
tv3.text = "CCC"
// 绑定机制的缺点3
button.text = "" // 人为失误,有隐患,让开发者犯错*/
}
}
ViewBinding 则不会产生上述的错误;因为我们通过 ViewBinding 只能访问到当前绑定的 xml 中的元素;
Fragment 中的基础使用
java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentBlankBinding fragmentBlankBinding = FragmentBlankBinding.inflate(getLayoutInflater());
return fragmentBlankBinding.getRoot();
}
和 Activity 的用法基本一致;
简单原理
我们开启 ViewBinding 之后,当声明一个 xml 的时候,会自动的在 moudlue -> build -> generated -> data_binding_base_class_source_out 下生成相关的类;

随便打开一个类看下:

本质上还是需要 findViewById 只是它帮我们生成了而已;
好了,ViewBinding 就讲到这里吧,本章只是对 DataBinding 进行一个铺垫,重点讲解 DataBinding,感兴趣的可以继续探索下 ViewBinding 的原理;
欢迎三连
来都来了,点个关注,点个赞吧,你的支持是我最大的动力~