1、可观察的数据对象
可观察性是指一个对象将其数据变化通知给其他对象的能力。通过数据绑定库,您可以让对象、字段或集合变为可观察。
1、可观察字段
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
可观察字段是具有单个字段的自包含可观察对象。要使用此机制,请采用 Java 编程语言创建 public final 属性,或在 Kotlin 中创建只读属性
private static class User {
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableField<String> lastName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
要访问字段值,请使用 set() 和 get() 访问器方法
user.firstName.set("Google");
int age = user.age.get();
2、可观察集合
某些应用使用动态结构来保存数据。可观察集合允许使用键访问这些结构。当键为引用类型(如 String)时,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"/>
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"/>
3、可观察对象
我们也可以通过Obserable接口的类注册监听,方便接收有关对象的属性的变化。
数据绑定库提供了用于实现监听器注册机制的 BaseObservable 类。实现 BaseObservable 的数据类负责在属性更改时发出通知。具体操作过程是向 getter 分配 Bindable 注释,然后在 setter 中调用 notifyPropertyChanged() 方法
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);
}
}
数据绑定在模块包中生成一个名为 BR 的类,该类包含用于数据绑定的资源的 ID。在编译期间,Bindable 注释会在 BR 类文件中生成一个条目。如果数据类的基类无法更改,则 Observable 接口可以使用 PropertyChangeRegistry 对象实现,以便有效地注册和通知监听器。
2、绑定类
数据绑定库可以生成用于访问布局的变量(data 标签)和视图(view)的绑定类。生成的绑定类将布局变量与布局中的视图关联起来。绑定类的名称和包可以自定义。所有生成的绑定类都是从 ViewDataBinding 类继承而来的。
系统会为每个布局文件生成一个绑定类。默认情况下,类名称基于布局文件的名称,它会转换为 驼峰 大小写形式并在末尾添加 Binding 后缀。以上布局文件名为 activity_main.xml,因此生成的对应类为 ActivityMainBinding。此类包含从布局属性(例如,user 变量)到布局视图的所有绑定,并且知道如何为绑定表达式指定值。
1、创建绑定对象
有四种形式
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
fragment 或者适配器使用
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
2、变量
数据绑定库为布局中声明的每个变量生成访问器方法。例如,以下布局在绑定类中针对 user、image 和 note 变量生成了 setter 和 getter 方法:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
3、ViewStubs
与普通视图不同,ViewStub 对象初始是一个不可见视图。当它们显示出来或者获得明确指示进行扩充时,它们会通过扩充另一个布局在布局中完成自我取代。
由于 ViewStub 实际上会从视图层次结构中消失,因此绑定对象中的视图也必须消失,才能通过垃圾回收进行回收。由于视图是最终结果,因此 ViewStubProxy 对象将取代生成的绑定类中的 ViewStub,让您能够访问 ViewStub(如果存在),同时还能访问 ViewStub 进行扩充后的扩充版视图层次结构。
在扩充其他布局时,必须为新布局建立绑定。因此,ViewStubProxy 必须监听 ViewStub OnInflateListener 并在必要时建立绑定。由于在给定时间只能有一个监听器,因此 ViewStubProxy 允许您设置 OnInflateListener,它将在建立绑定后调用这个监听器。
4、动态变量
有时,系统并不知道特定的绑定类。例如,针对任意布局运行的 RecyclerView.Adapter 不知道特定绑定类。在调用 onBindViewHolder() 方法时,仍必须指定绑定值。
在以下示例中,RecyclerView 绑定到的所有布局都有 item 变量。BindingHolder 对象具有一个 getBinding() 方法,这个方法返回 ViewDataBinding 基类。
public void onBindViewHolder(BindingHolder holder, int position) {
final T item = items.get(position);
holder.getBinding().setVariable(BR.item, item);
holder.getBinding().executePendingBindings();
}
5、自定义绑定类名称
默认情况下回根据xml名称以首字母大写驼峰形式产生绑定类。但有时候也可以自己定义。
<data class="ContactItem">
…
</data>
3、绑定适配器
这里的适配器是xml里对象的一些行为需要代码去实现。