前言
可觀察性(Observability)是指一個物件具有當其數據發生變化時通知其他元件的能力。
Data Binding Library讓物件,欄位,集合具有可被觀察的能力
任何的 POJO 都可以使用於 Data Binding,但修改該物件時並不會讓 UI 也跟著更新。 Data Binding 可為數據對象(data object)提供在其數據更改時通知其他對象(稱為偵聽器)的能力。
可觀察類別(observable class)有 3 種類型,objects,fields,collections
當上列3種可觀察類別的物件綁定了 UI,且物件的屬性(property)發生變化時,UI 將會自動更新。
Observable fields
因為去建立實作 Observable 介面的類別需要一些額外工作,因此若開發者僅有少量的屬性其實是不值得的,在這種情況下可以使用一般性可觀察類別,如下
ObservableBoolean | ObservableByte | ObservableChar | ObservableShort |
ObservableInt | ObservableLong | ObservableFloat | ObservableDouble |
ObservableParcelable |
Observable fields 是具有單一欄位的自包含可觀察物件,使用方式為建立一個 public final 屬性,如下
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 objects 代替 observable fields,可提供額外的好處。參考 Use LiveData to notify the UI about data changes
Observable collections
有些 App 使用動態資料結構來持有數據,observable collections 為提供這些動態資料結構。
ObservableArrayMap 用於當鍵值為參考型別時特別有用,如下
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
在 layout 檔案中,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"/>
ObservableArrayList 則適用於當鍵值為 integer 時,如下
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
在 layout 檔案中,list 使用如下
<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
當類別實作了 Observable 介面便可提供註冊監聽器,該監聽器可讓想觀察的元件可取得通知。
Observable 介面具有加入和移除監聽器的機制,但開發者必須決定何時送出通知。為了讓過程更簡單,Data Binding Library 提供了 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); } }
Data Binding 會在 module package 產生一個 BR 的類別,該類包含用於數據綁定的資源的 ID。
Bindable 註釋在編譯期間會產生一個 entity 到 BR 類別。
如果無法更改 data class 的 base class,則可以使用 PropertyChangeRegistry 實現 Observable 接口,以有效地註冊和通知監聽器。
Article Comments