框架組件(二)Data Binding 3-結(jié)合Observerable數(shù)據(jù)對象

該系列文章是對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 類和以下特定的類讓字段可觀測。

可觀測字段是包含單個(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)聽器。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容