Android Jetpack 之ViewBinding和DataBinding

前言

Jetpack 是一套庫、工具和指南,可幫助開發者更輕鬆地編寫優質應用。

現在無論走到哪兒,如果Android開發者說自己不瞭解Jetpack,怕是會被人”鄙視“的看一眼,從今天開始,我會寫一系列Jetpack的文章,讓我們一起來學習強大的Jetpack吧。

ViewBinding

通過視圖綁定,系統會爲模塊中的每個 XML 佈局文件生成一個綁定類,通過綁定類,我們可以直接操作控件id,而不需要findViewById,這樣我們可以避免控件id無效出現的空指針問題。

首先我們新建項目,新建MainActivity,對應的佈局文件名爲:activity_main,在模塊的build.gradle中開啓視圖綁定:

viewBinding {
    enabled = true
}

編譯後,系統會自動生成名爲ActivityMainBinding,我們在activity_main.xml 添加一個文本框和一個按鈕

<EditText
    android:id="@+id/ed_input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/btn_save"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="保存" />

接下來 修改MainActivity中的代碼

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding activityMainBinding = ActivityMainBinding.inflate(LayoutInflater.from(this));
    setContentView(activityMainBinding.getRoot());
}

接下里我們就可以直接使用id對應的控件了

activityMainBinding.btnSave.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String content = activityMainBinding.edInput.getText().toString();
        Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
    }
});

運行結果如圖

ViewBinding只是爲了替代findViewById,優點就是空安全,不過有了kotlin-android-extensions之後,ViewBinding用的應該比較少了吧。

DataBinding

數據綁定簡單的解釋就是,之前我們需要通過獲取控件 通過控件設置數據,現在有了數據綁定 我們可以直接在佈局文件中直接綁定數據。

和ViewBinging一樣 使用前 首先我們在build.gradle 中配置

dataBinding {
    enabled = true
}

新建Main2Activity,對應佈局如下:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main2Activity">

</layout>

使用數據綁定的xml文件根佈局必須是layout標籤,我們新建一個User類,有姓名和性別字段

public class User {
    ....
    private String userName;
    private String userGender;
    ....
}

 

首先通過data標籤導入要綁定的數據

<data>
    <variable
        name="user"
        type="com.example.jetpackdemo.bean.User" />
</data>

我們在xml中加入兩個textView用來顯示用戶姓名和性別

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{user.userName}"
        android:textSize="17sp" />


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{user.userGender}"
        android:textSize="17sp" />
</LinearLayout>

通過@{}的引用方式設置數據

在Main2Activity中通過如下方法 設置數據源:

ActivityMain2Binding activityMain2Binding = DataBindingUtil.setContentView(this, R.layout.activity_main2);
User user = new User("黃林晴", "男");
activityMain2Binding.setUser(user);

運行程序如下所示:

如果我們現在把性別改爲null,則性別會直接不顯示

如果我們現在要求當性別爲null的時候顯示“未設置”要怎麼做呢,我們可以在xml中進行判斷

在data標籤下導入TextUtil 

<import type="android.text.TextUtils" />
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text='@{TextUtils.isEmpty(user.userGender)? "未設置": user.userGender}'
    android:textSize="17sp" />

運行結果如下圖所示

除了數據綁定外,還有監聽事件綁定等,就不詳細舉例了。我們當前做的是靜態數據綁定,很多時候我們都需要動態綁定,那麼如何在數據變化的時候自動更新呢?

使用可觀察的數據對象

  • 可觀察字段

可觀察數據類型 類型如下:

修改User類字段屬性如下:

public class User {

    public final ObservableField<String> userName = new ObservableField<>();
    public final ObservableField<String> userGender = new ObservableField<>();

}

注意 這裏必須定義爲final類型,在Main2Activity中如下所示:

ActivityMain2Binding activityMain2Binding = DataBindingUtil.setContentView(this, R.layout.activity_main2);
User user = new User();
user.userName.set("黃林晴-初始值");
user.userGender.set("男");
activityMain2Binding.setUser(user);

運行結果如下所示:

接下來 我們添加一個按鈕 在按鈕中重新設置user中的數據

btnChanged = findViewById(R.id.btn_change);
btnChanged.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        user.userName.set("黃林晴-改變後的值");
    }
});

點擊按鈕,運行結果如下所示:

如此一來數據變化的時候我們控件上的數據也就可以變化了

  • 可觀察集合

可觀察集合 常用於動態數據結構,使用ObservableArrayMap訪問鍵值類似HashMap中的數據訪問,這裏不做介紹了。

  • 可觀察對象

和可觀察數據字段和集合相比,我們最喜歡的應該是可觀察對象了,這樣我們我們不需要受原有訪問數據方法的限制

public class User extends BaseObservable {

    private String userName;
    private String userGender;

    public User(String userName, String userGender) {
        this.userName = userName;
        this.userGender = userGender;
    }

    @Bindable
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
        notifyPropertyChanged(BR.userName);

    }

    @Bindable
    public String getUserGender() {
        return userGender;
    }

    public void setUserGender(String userGender) {
        this.userGender = userGender;
        notifyPropertyChanged(BR.userGender);
    }
}

我們讓User類繼承自BaseObservable,使用Bindable註解註冊通知,當值改變的時候通過notifyPropertyChanged()發送通知,爲BR 類是數據綁定生成的一個用於數據綁定的資源的 ID的類。在Main2Activity中同樣的設置初始值,點擊按鈕改變值

ActivityMain2Binding activityMain2Binding = DataBindingUtil.setContentView(this, R.layout.activity_main2);
User user = new User("黃林晴-可變對象", "男");
activityMain2Binding.setUser(user);
btnChanged = findViewById(R.id.btn_change);
btnChanged.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        user.setUserName("黃林晴-數據更新");
    }
});

運行後點擊按鈕結果如下:

Android Studio 3.1 及更高版本允許用 LiveData 對象替換可觀察字段,結合JetPack的使用,數據通知都推薦使用LiveData了,等我們講到LiveData的時候回重新使用這個例子。

DataBinding和ViewBinding 到這裏,我們已經可以使用基礎的功能了,後續在項目開發中還需要多實踐操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章