Data Binding

Data BindingAndroid待發布的支持庫,它能夠將邏輯和代碼關聯起來,避免開發者書寫大量的膠合代碼,也是實現MVVM架構的必要技術。android

此前,佈局文件XML被認爲是相對靜態的,每每須要在Java代碼中處理與其有關的邏輯;數據綁定技術(Data Binding)改造了佈局文件使其可以導入Java類,定義和使用變量,具有像Java代碼同樣的靈活性,從而使得XML文件變的更加動態化,支持更強大的功能。架構

添加依賴

在項目頂層的gradle中添加依賴app

dependencies {
    classpath "com.android.tools.build:gradle:1.2.3"
    classpath "com.android.databinding:dataBinder:1.0-rc0"
}

在具體模塊gradle配置文件中啓用該插件函數

apply plugin: 'com.android.databinding'

使用示例

給出一個Model層的User佈局

public class User {
   public final String firstName;
   public final String lastName;
   //get&set
    ....
}

View層使用一個TextView專門負責顯示User的兩個名字。
在通常的實現中,TextViewUser類每每都在Activity中實例化,並實現交互邏輯。在MVP架構中,專門設立主導器P負責交互邏輯,並將User類的實例化從Activity中移出。
使用數據綁定能夠在TextView的佈局文件中就用User對象指定其顯示的內容。這個佈局文件databinding_layout.xml以下gradle

//1.根標籤爲 layout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    //2.data標籤訂義所使用數據域對象
    <data>
        //3.variable標籤根據Java類創建變量
        <variable
            name="user" //聲明變量名稱
            type="com.example.migratingtest.User" //指定變量類型
        />
    </data>
    //4.靜態佈局
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_margin="20dp"
            android:padding="20dp"
            android:background="#55ffff00"
            //5.用@{user.firstName}格式使用定義的類對象user
            android:text="@{user.firstName}+@{user.getLastName()}"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

</layout>

佈局文件中定義了數據層user和視圖層textview的對應關係,但要傳入的對象user還須要在Java代碼中生成;同時這個佈局文件將按名稱生成一個DatabindingLayoutBinding類,位於app\build\intermediates\classes\debug\<包名>\databinding目錄下,須要在Java代碼中做爲佈局載入;然後將兩者綁定起來。ui

//1.載入新佈局類
DatabindingLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.databinding_layout);
//2.產生User對象
User user = new User("liu", "xiangtian");
//3.綁定佈局和具體對象
binding.setUser(user);

更多用法

佈局文件中data能夠像Java代碼同樣導入類,並直接使用其類靜態變量/方法,使用variable標籤聲明和創建對象;this

類和對象的域/方法都可以在佈局文件中使用,也支持相關運算,如上例中的字符鏈接符+spa

觀察者模式

上述僅是數據綁定的基本功能,若是User對象一被改變,佈局界面就自動更新,數據綁定才顯得名副其實。其實現很容易讓人聯想到觀察者模式,User對象繼承Observable做爲被觀察者,但問題是這種實現更新須要主動使用notify函數來通知觀察者們;爲此,android使用BaseObservable類和Bindable註解實現自動通知。插件

要改的僅僅是User類。

//1.繼承BaseObservable類成爲被觀察者
public class User extends BaseObservable{
    public String firstName;

    //2.給get方法Bindable註解
    @Bindable
    public String getFirstName() {
        return firstName;
    }
    //3.給set方法添加`notify`方法
    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }

}

BR亦是編譯時生成類,一樣位於app\build\intermediates\classes\debug\<包名>\目錄下,其內容是:

public class BR {
    public static final int _all = 0;
    public static final int firstName = 1;
    public static final int lastName = 2;
    public static final int user = 3;
}

此後當使用user.setFirstName("li")更改數據後,佈局中將相應變化。

BR代碼可知,User類中全部域均被編入被觀察者列表中,這有時並不合理。爲了靈活起見,可使用ObservableFields單獨對某個引用域進行轉換,使用ObservableInt等對基本類型進行轉換。

依然改User

public class User {
    public ObservableField<String> firstName = new ObservableField<>();
    public ObservableField<String> lastName = new ObservableField<>();
}

在Java代碼中初始化User

User user = new User();
//ObservableField是一個包裝類,提供get/set方法處理包裝的內容對象
user.firstName.set("liu");
user.lastName.set("xiangtian");

佈局文件仍然使用@{user.firstName}便可,不須要使用@{user.firstName.get}

綁定關係類

生成的新佈局文件是一個表明綁定關係的類DatabindingLayoutBinding,這個類繼承自ViewDataBinding,其中包含全部在佈局中聲明瞭的類對象 和 參與綁定的所有View,並提供了相應了set/get方法以及解除全部綁定的unbind方法。如示例中

// views
private final android.widget.LinearLayout mboundView0;
private final android.widget.TextView mboundView1;
// variables
private com.example.migratingtest.User mUser;
相關文章
相關標籤/搜索