該系列文章是對Android推出的架構(gòu)組件相關(guān)文章,按作者自己理解來翻譯的,同時(shí)標(biāo)記有作者自己一些簡單筆記。如果讀者發(fā)現(xiàn)文中有翻譯不準(zhǔn)確的地方,或者理解錯(cuò)誤的地方,請不吝指教。
源自Google官方
Data Binding Library 一文的翻譯與歸納
其他相關(guān)鏈接:
Android Jetpack Components
[TOC]
可觀測性是指一個(gè)對象能夠在數(shù)據(jù)改變時(shí)通知其它對象。Data Binding 庫允許你使用可觀測的對象、字段或集合。
Data Binding庫可以使用任何普通的對象,但是改變這些對象時(shí)不會自動(dòng)觸發(fā)UI更新。Data Binding 可以為你的數(shù)據(jù)對象提供數(shù)據(jù)改變時(shí)通知其他對象的能力,這里有三種不同的可觀測類類型:對象、字段和集合。
當(dāng)UI綁定了可觀測數(shù)據(jù)對象并且數(shù)據(jù)對象的一個(gè)屬性發(fā)生改變時(shí),UI會自動(dòng)刷新。
Observable fields(可觀測字段)
要實(shí)現(xiàn) Observable 接口會有一些工作量,如果你的類只有幾個(gè)屬性,那么這些工作是不值得的。基于這點(diǎn),你可以使用通用的 Observable 類和以下特定的類讓字段可觀測。
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
可觀測字段是包含單個(gè)字段的可觀測對象。原始版本在訪問操作時(shí)避免裝箱和拆箱操作。要使用此機(jī)制,需要在Java代碼中創(chuàng)建公用的final屬性,或在Kotlin中創(chuàng)建只讀屬性。如下代碼所示:
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();
注意:Android Studio 3.1 或以上版本可以使用 LiveData 對象來替代可觀測對象,這種做法更有益于你的應(yīng)用。
Observable collections(可觀測集合)
一些應(yīng)用使用動(dòng)態(tài)結(jié)構(gòu)來保存數(shù)據(jù),可觀測集合可以使用 key 來訪問這些結(jié)構(gòu)。當(dāng) key 是引用類型時(shí),比如 String,ObservableArrayMap 類是很好的選擇,如下所示:
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);
在布局中,可以通過 key 獲取 map 中的值,如下:
<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"/>
當(dāng) key 是 int 類型時(shí),可以選擇 ObservableArrayList,如下:
ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);
再布局中可以通過下表來訪問列表中的數(shù)據(jù),如下:
<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 objects(可觀測對象)
一個(gè)實(shí)現(xiàn)了 Observable 接口的類,允許注冊監(jiān)聽可觀測對象的數(shù)據(jù)改變。
Observable 接口有添加和移除監(jiān)聽的機(jī)制,但是你必須決定什么時(shí)候發(fā)送通知。為了讓開發(fā)更容易,DataBinding 庫提供了 BaseObservable 類,它已經(jīng)實(shí)現(xiàn)了監(jiān)聽器注冊機(jī)制。繼承自 BaseObservable 的數(shù)據(jù)類主要負(fù)責(zé)屬性改變時(shí)進(jìn)行通知。為 getter 方法添加 @Bindable 并在 setter 中調(diào)用 ntifyPropertyChanged() 通知屬性改變,如下所示:
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);
}
}
DataBinding 會為 module 中使用了數(shù)據(jù)綁定的 ID 和資源生成 BR 類。編譯時(shí)在 BR 類中生成 Bindable 注解的條目。如果無法修改數(shù)據(jù)類的基類,可以使用 PropertyChangeRegistry 對象來實(shí)現(xiàn) Observable 接口,以實(shí)現(xiàn)注冊和通知監(jiān)聽器。