可观察的数据对象提供了当数据变化时通知其他对象的能力。Data Binding
库提供了使对象、字段和集合可观察的能力。
任何的传统对象都可以用于 Data Binding
,但是这些对象数据发生变化时并不能通知 UI
更新。Data Binding
提供了使数据可观察的方法,就像 Listeners
一样,它提供了三种可观察的类:对象(objects
)、字段(fileds
)和集合(collections
)。
当这些可观察的数据对象与 UI
绑定后,数据变化时会自动更新 UI
。
可观察的字段(observable fields
)
Data Binding
已经为我们写好了用于观察基础类型的类,它们都实现了 Observable
接口:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
使用方法是,在 java
类中创建 public final
属性,在 kotlin
中创建只读属性,如下所示:
class User {
val firstName = ObservableField<String>()
val lastName = ObservableField<String>()
val age = ObservableInt()
}
private static class User {
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableField<String> lastName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
可以使用 get()
和 set()
方法,访问这些可观察字段的值,如下所示:
user.firstName.set("Google");
int age = user.age.get();
可观察的集合
对于 key
是引用类型的时候,可以使用 ObservableArrayMap
,如下所示:
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user.age)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
对于 key
是整型,可以使用 ObservableArrayList
,如下所示:
ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
可观察的对象
当一个类实现了 Observable
接口,它就可以允许外界注册监听器来监听它的属性的变化。
Observable
可以允许外界注册/移除监听器,但是变化通知的发送是由我们自己来控制的。为了方便我们开发,Data Binding
提供了 BaseObservable
,它默认实现了监听器的注册和移除,我们可以直接继承 BaseObservable
,只负责发送变化通知就行了。变化通知的发送,需要我们给类属性的 get()
方法加上 Bindable
注解,并在 set()
方法里调用 notifyPropertyChanged()
方法,示例如下:
class User : BaseObservable() {
@get:Bindable
var firstName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.firstName)
}
@get:Bindable
var lastName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.lastName)
}
}
Data Binding
会在编译时自动生成一个叫做 BR
的类,这个类包含了属性的 ID。