Jetpack学习-4-DataBinding
使用
android {
....
// AndroidStudio 4.0 建议使用buildFeatures.dataBinding替代(dataBinding.enabled)
buildFeatures.dataBinding = true
}
然后同步
新建继承自BaseObservable类
public class User extends BaseObservable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Bindable
public String getName() {
return name;
}
@Bindable
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(com.example.myapplication.BR.name);
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(com.example.myapplication.BR.age);
}
}
在字段get方法上添加@Bindable注解,在set方法里添加notifyPropertyChanged(包名.BR.属性名)
注意:开发的时候可能无法找到 包名.BR 这个类,需要先@Bindable后,再Make Project自动生成BR类。每增加一个@Bindable属性,需要Make Project一次,否则无法找到BR.xx。(建议一个类一次写完@Bindable 的get方法,然后Make Project生成BR对应属性后再写set方法)
build工程
在新布局文件,布局最外层节点按option+enter(window中alt+enter),弹出Convert to data binding layout。转换成DataBinding格式布局。
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="user"
type="com.example.myapplication.databinding.User" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".databinding.DataBindActivity">
<TextView
android:id="@+id/tvUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="更新"
android:textSize="26sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50dp"
android:text="@{user.name}"
android:textSize="26sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="100dp"
android:text="@{String.valueOf(user.age)}"
android:textSize="26sp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
layout作为最外层节点,增加一个data节点,增加veriable节点,配置name(随意名字)和type属性。text赋值@{user.name}绑定User类的name。name发生改变,text属性就会改变。
Activity绑定User和布局
public class DataBindActivity extends AppCompatActivity {
private User user;
private ActivityDataBindBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_data_bind);
binding = DataBindingUtil.setContentView(this, R.layout.activity_data_bind);
user = new User("小名", 18);
binding.setUser(user);
findViewById(R.id.tvUpdate).setOnClickListener(v -> {
user.setName(user.getName() + "&");
user.setAge(user.getAge() + 1);
binding.setVariable(BR.user, user);
});
}
}
通过DataBindingUtil.setContentView(this, R.layout.activity_data_bind);来绑定,并返回bind,然后通过setUser方法给布局设置数据
原理
app/buil/intermediates/data_binding_layout_info_type_merge/debug/mergeDebugResources/out/目录下activity_databinding-layout.xml文件(在原来的布局文件加了-layout),最外层节点记录了对应的布局文件,通过Variables节点,记录对应的数据。Targets节点记录原布局tag,通过Expression节点记录对应的数据。
app/build/intermediates/incremental/mergeDebugResources/stripped.dir/layout/目录下activity_databinding.xml文件,添加了一些tag和前面activity_databinding-layout.xml对应。
DataBindingUtil.setContentView(this, R.layout.activity_databinding)-->setContentView-->bindToAddedViews-->bind-->getDataBinder(sMapper)-->DataBinderMapperImpl(自动生成)