用于解决数据绑定的问题,采用了MVVM模式,实现数据双向绑定。
使用前提:
使用databind需要使用Gradle 的 Android Plugin 1.5 以上的版本。然后在app 模块的gradle文件中进行声明:
android {
....
dataBinding {
enabled = true
}
}
简单例子:
1.在layout.xml文件中声明使用databind
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
然后使用<data>和<variable>标签声明数据变量。属性name是变量名称,type是变量类型。使用时在view的参数中使用android:text="@{user.lastName}"进行赋值。
2.User类中被view使用的变量必须有对应的getter函数。
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
}
3.Android的databind工具会自动根据layout文件生成相应的binding类,命名方法是根据对应的xml布局文件产生。如main_activity.xml。会将第首字母大写且去掉下划线拼接而成,即MainActivityBinding。所有的产生类全部继承于android.databinding.ViewDataBinding。
在Java代码中使用下面代码进行绑定:
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
MainActivityBinding binding = MainActivityBinding.*inflate*(getLayoutInflater());
MainActivityBinding binding = MainActivityBinding.*inflate*(getLayoutInflater());
可以类比于Android中的View加载:
如:
1. 直接加载
findViewById:TextView tv=(TextView)findViewById(R.id.tv);
2. 动态加载
TextView tv =view.inflate()
4.view绑定后,需要在合适的时候对model进行绑定,
User user = new User(“Test”, “User”);
binding.setUser(user);
注意,此时data并不是双向绑定的,而databing在这里只是起到了一个findViewById的作用,要想实现双向绑定,即每当data数据改变时View中的布局也相应改变。
- 让User类继承BaseObservable。
代码如下
private static class User extends BaseObservable {
private String firstName;
private String lastName;
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
}
使用@Bindable 对getter方法进行注解,并且在setter方法的时候,显性调用 notifyPropertyChanged方法,其中BR.xxx变量为Android databind 工具生成。
- ObservableFields
上述方式比较麻烦,Android databind 提供了ObservableField类。以及一些基础类型的包装类,ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, ObservableParcelable 用法如下:
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
user.firstName.set("Google");
int age = user.age.get();
Observable 定义的变量,必须使用 getter 和 setter进行取值赋值操作。
还可以定义Observable集合,ObservableArrayMap 。