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 提供的具有觀察能力的欄位、對象、集合了,下面是上述代碼的測試效果圖: