1. 导入
在module的build.gradle中声明
android {
dataBinding {
enabled true
}
}
如果依赖库中使用了DataBinding,则module也要使用DataBinding才行。
Android Gradle Plugin 3.1.0 canary 6提供了另外一种新的DataBinding编译器V2,具体启用方式是:
// gradle.properties
android.databinding.enableV2=true
v1和v2互不兼容。相对于v1编译器,v2编译器具有以下特点:
避免无关报错。ViewBinding类是由Gradle插件负责生成的,而不是Java编译器,所以不会像之前由于Java中其他无关问题报错。
编译效率提高。v1中每次编译app的时候都会重新生成绑定类,而在v2中则会保留已生成类,不会重新生成,提高效率。
v1中可以手动提供binding adapter覆盖依赖库中的adapter,而在v2当中,app中手动提供的binding adapter则只会对所应用到的library或module生效。
不同配置资源文件夹下的同一个布局文件中,如果存在同id不同类的View,则v1中会自动确定最通用的父类,而在v2中,则自动指定为View类。
v2中不同module不能在manifest中使用相同包名,因为V2使用包名来生成绑定类。
2. 设置布局
DataBinding中的布局文件需要在传统的外层布局套上一层标签:
<layout>
<FrameLayout/>
</layout>
编译后会自动生成Binding类,类名以XML文件名的每个单词首字母大写,再加上Binding组合而成,比如activity_main.xml生成的类名是ActivityMainBinding。
在Android Studio当中,生成的绑定类位于app/build/generated/source/apt/debug/包名/databinding/ 目录下。
如果要自定义生成的类名,可以在标签中声明class属性进行设置。
3. 绑定布局
在Activity中将布局绑定到Activity上,获取绑定类:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
}
对于ListView或者RecyclerView中的绑定,可以使用以下两种方式之一:
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// 或者
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
注意在列表例如RecyclerView中,如果一个变量或者observable改变了,binding会在下一帧时改变,如果需要binding马上执行,需要手动调用 executePendingBindings()
:
public void onBindViewHolder(BindingHolder holder, int position) {
final T item = mItems.get(position);
holder.getBinding().setVariable(BR.item, item);
holder.getBinding().executePendingBindings();
}
DataBinding会为布局文件里所有具备id的View生成相应public final的字段,字段名即id名。这是通过遍历一次布局层级完成的,会比对多个view调用findViewById()效率更高。
ViewStub
对于布局中的ViewStub,DataBinding对应的生成类是ViewStubProxy,因为ViewStub被inflate或者可见之后就被其他布局替代了,所以DataBinding提供ViewStubProxy来获取ViewStub以及inflated之后的布局,inflate之前ViewStub非空,内含布局为空,inflate之后ViewStub为空,内含布局非空。