PS:真正的努力发生在行动之后。
上篇文章介绍了 BindAdapter
,Android Jetpack 组件系列文章如下:
- Android Jetpack 组件之 Lifecycle 篇
- Android Jetpack 组件之 LiveData 篇
- Android Jetpack 组件之 ViewModel 篇
- Android Jetpack 组件之 DataBinding 篇
- Android Jetpack 组件之 BindingAdapter 篇 - jzman
本篇文章将介绍如何使用可观察的数据对象,可观察性是指某个对象变化通知其他数据的能力,主要有三种可观察类型:
- 字段
- 对象
- 集合
使用数据绑定可对数据对象提供在数据更改时通知其他数据更改的能力,将一个可观察数据对象绑定到 UI 上,当数据对象的属性发生变化可自动更新 UI。
字段#
如果某个类只有几个属性,为了使得这些对象具有观察数据变化的能力,可以使用可观察字段 (Observable fields) 来实现,databinding 中提供了这样的通用 Observable 类,包括八种基本数据类型以及 Parcelable 类型,具体如下:
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
那就来使用一下,这里以字符串和 Int 来说明可观察字段的使用,首先创建一个实体类如下:
/**
* Powered by jzman.
* Created on 2018/12/3 0003.
*/
public class Person {
public final ObservableField<String> name = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
然后,在布局文件中声明要使用的变量,具体如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="person"
type="com.manu.databindsample.data.Person"/>
</data>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`name is `+person.name+`,age is `+person.age}"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="btnClickObservableField"
android:text="可观察字段"/>
</LinearLayout>
</layout>
然后,在对应的 Activity 中绑定数据对象,具体如下:
private Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityObservableObjectSampleBinding binding =
DataBindingUtil.setContentView(this,R.layout.activity_observable_object_sample);
person = new Person();
binding.setPerson(person);
}
最后,动态修改 person 的值,当 Person 对象的属性值发生变化就会动态更新其属性值,进而动态更新 UI,具体如下:
//动态修改属性值
public void btnClickObservableField(View view) {
person.name.set("android");
person.age.set(10);
}
以上就是可观察字段的使用,其关键还是观察者设计模式,文末看测试效果图。
对象#
在使用 databinding 时,databinding 提供了一个接口 android.databinding.Observable,某个类实现了这个接口就可以注册一个监听器,这个监听器会监听某个数据对象的变化,进而通知该数据对象的属性的变化,这个 Observable 接口有有添加和删除监听器的机制,但何时发送数据更新的通知由具体的实现类决定,为了简化开发,可以使用提供的 BaseObserable,该类实现了监听器注册机制,具体继承 BaseObservable 的类决定属性何时更改,即在相应的 getter 方法上使用注解 @Bindable,在相应的 setter 方法上调用对应的 notifyPropertyChanged 方法,下面来看一看可观察对象的具体使用方式,首先,创建一个数据实体类如下:
/**
* 可观察的数据对象
* Powered by jzman.
* Created on 2018/12/4 0004.
*/
public class Student extends BaseObservable{
private String name;
private int age;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
}
然后,在布局文件中声明要使用的变量,具体如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="student"
type="com.manu.databindsample.data.Student"/>
</data>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`name is `+student.name+`,age is `+student.age}"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="btnClickObservableObject"
android:text="可观察对象"/>
</LinearLayout>
</layout>
然后,在对应的 Activity 中绑定数据对象,具体如下:
private Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityObservableSampleBinding binding =
DataBindingUtil.setContentView(this,R.layout.activity_observable_sample);
//可观察对象
student = new Student();
binding.setStudent(student);
}
最后,动态修改 student 的值,当 Student 对象的属性值发生变化就会动态更新其属性值,进而动态更新 UI,具体如下:
public void btnClickObservableObject(View view) {
student.setName("可观察对象");
student.setAge(20);
}
以上就是可观察对象的使用,文末看测试效果图。
集合#
在开发过程中往往涉及到集合数据,databinding 中也提供了具有观察能力的集合类,这里以最常用的 Map 和 List 集合来说明 ObservableMap 和 ObservableList 的使用,首先,在布局文件中声明要使用的变量,具体如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!--ArrayMap-->
<import type="android.databinding.ObservableArrayMap"/>
<variable
name="arrayMap"
type="ObservableArrayMap<String,String>"/>
<!--ArrayList-->
<import type="android.databinding.ObservableList"/>
<variable
name="arrayList"
type="ObservableList<String>"/>
</data>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`name is `+arrayMap.name+`,age is `+arrayMap.age}"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="btnClickObservableMap"
android:text="可观察集合之ArrayMap"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`name is `+arrayList[0]+`,age is `+arrayList[1]}"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="btnClickObservableList"
android:text="可观察集合之ArrayList"/>
</LinearLayout>
</layout>
然后,在对应的 Activity 中绑定及和数据对象,具体如下:
private ObservableArrayMap<String,String> arrayMap;
private ObservableArrayList<String> arrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityObservableSampleBinding binding =
DataBindingUtil.setContentView(this,R.layout.activity_observable_sample);
//可观察集合之ArrayMap
arrayMap = new ObservableArrayMap<>();
binding.setArrayMap(arrayMap);
//可观察集合之ArrayList
arrayList = new ObservableArrayList<>();
binding.setArrayList(arrayList);
}
最后,绑定集合数据之后,就可以修改集合数据来观察 UI 的变化,具体如下:
//可观察集合之ArrayMap
public void btnClickObservableMap(View view) {
arrayMap.put("name","可观察集合之ArrayMap");
arrayMap.put("age","30");
}
//可观察集合之ArrayList
public void btnClickObservableList(View view) {
arrayList.add("可观察集合之ArrayList");
arrayList.add("40");
}
以上就是可观察集合的使用。
测试效果#
通过上面的小案例,相信可以非常轻松的使用 databinding 提供的具有观察能力的字段、对象、集合了,下面是上述代码的测试效果图: