在Android Studio 2.1 Preview 3之后,官方开始支持双向绑定了。
什么是双向绑定呢?
下面是Data Binding的基本使用:
<layout ...>
<data>
<variable type="com.example.myapp.User" name="user"/>
</data>
<RelativeLayout ...>
<EditText android:text="@{user.name}" .../>
</RelativeLayout>
</layout>
上面的EditText的text属性和对象user的name属性进行了绑定,但是代码如果只像上面这样这样的话,那EditView的text只会在第一次设置binding.setUser(user)的时候被赋予user.name值,之后如果user.name值变化的时候,EditView的text值不会变化。
我们理想的情况是user.name值变化的时候,EditText的text值也同时自动变化,同样,EditText的text值变化的时候,user.name值也同时自动变化。
那所谓双向绑定,包括正向绑定和反向绑定,
正向绑定:当user的name值变化的时候,EidtView的text也同时变化;
反向绑定:当EidtView的text变化的时候,user对象的name值也同时变化。
怎么实现正向绑定呢?
正向绑定
方法一:继承Observable的方式
具体如下:
1.我们的实体类(User类)继承BaseObservale类
2.Getter上使用注解@Bindable
3.在Setter里调用方法notifyPropertyChanged
让User类继承BaseObservable:
public class User extends BaseObservable
{
private String name;
@Bindable
public String getName() {
return username;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged( BR.name);
}
}
注意:当Getter方法getName()上加@Bindable以后,会自动在com.android.databinding.library.baseAdapters包的BR类中加了name属性
原理:当代码中设置user的name属性的时候user.setName(name),调用notifyPropertyChanged(BR.name),这个方法在BaseObservable类中定义,它会根据BR.name这个ID去通知相应的UI进行更新。以上就在user的name属性变化以后,EditView的text会自动的发送变化,就实现了正向绑定。
方法二:定义ObservableField方式
如果所有要绑定的都需要创建Observable类,那也太麻烦了。所以Data Binding还提供了一系列Observable,包括 ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, 和ObservableParcelable。我们还能通过ObservableField泛型来申明其他类型,如:
private static class User {
public final ObservableField<String> firstName =new ObservableField<>();
public final ObservableField<String> lastName =new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
而在xml中,使用方法和普通的String,int一样,只是会自动刷新,但在java中访问则会相对麻烦:
user.firstName.set("Google");
int age = user.age.get();
那怎么实现反向绑定呢?
对于一部分属性,在XML中的引用中把“@{}”改成“@={}”,比如:
<layout ...