Data Binding
Data Binding即資料綁定,Data Binding 庫實作在布局檔案中實作資料綁定申明,使資料的變化引起視圖的自動更新,減少了邏輯代碼,在Android中可以很友善的實作MVVM的開發模式。
MVVM
了解MVVM之前,我們先簡單說一下MVC、MVP模式。
MVC是Model(模型)---View(視圖)---(Controller)控制器的縮寫,它用一種将業務邏輯、資料、界面顯示分離的方法組織代碼,将業務邏輯聚集到一個部件裡面,在改進和個性化定制界面及使用者互動的同時,不需要重新編寫業務邏輯。将系統進行MVC分層的核心思路就是分離元件,降低元件耦合性,元件獨立演化。
MVP是Model--View--Presenter的縮寫,MVP與MVC的主要差別是在MVP中View并不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進行的,所有的互動都發生在Presenter内部,而在MVC中View會從直接Model中讀取資料而不是通過 Controller。模型與視圖完全分離,我們可以修改視圖而不影響模型,可以更高效地使用模型,因為所有的互動在Presenter裡面。
MVVM是Model-View-ViewModel的縮寫,Model提供資料、View負責顯示、ViewModel負責邏輯的處理,與MVP的差別是,ViewModel與View之間采用雙向綁定(data-binding):View的變動,自動反映在 ViewModel,反之ViewModel的變化自動引起View的改變 。ViewModel作為View的資料映射,通常View上有什麼屬性,ViewModel上也會存在相應的一個屬性,這兩個屬性通過事件實作了雙向的綁定,Data Binding Library 替我們完成了這樣的綁定過程。 MVVM的幾個優點:
1. 低耦合: 視圖(View)可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當View變 化的時候Model可以不變,當Model變化的時候View也可以不變。
2. 可重用性: 你可以把一些視圖邏輯放在一個ViewModel裡面,讓很多view重用這段視圖邏輯。
3. 可測試: 界面素來是比較難于測試的,而現在測試可以針對ViewModel來寫。
環境搭建
Data Binding 插件需要Gradle 1.3以上及Android Studio 1.3.
配置Guide檔案:添加Data binding 包路徑
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:1.3.0-beta1"
classpath "com.android.databinding:dataBinder:1.0-rc0"
}
}
然後確定jcenter是在子項目的庫清單中
allprojects {
repositories {
jcenter()
}
}
在android插件後面添加dataBinding插件
apply plugin: ‘com.android.application'
apply plugin: 'com.android.databinding'
如何使用Data Binding
支援 Data Binding的布局檔案和以前的布局檔案不一樣,它的跟節點不再是一個ViewGroup,而是layout,并且多了一個data節點。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
在data節點裡面的variable聲明實作資料與UI的綁定,變量為UI提供資料,通過@{ } 可以直接把Java 中定義的屬性指派給UI:
<span style="white-space:pre"> </span>android:text="@{user.firstName}
資料對象
任何Java對象對象(POJO)可以做資料綁定。
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
}
這種綁定以後成員屬性改變卻不會讓UI進行更新。
要實作成員變更時,UI随着自動更新,首先得有一個實作了 android.databinding.Observable 的類,Android 原生提供了已經封裝好的一個類 - BaseObservable,并且實作了監聽器的注冊機制。 資料類的實作者仍然有責任讓成員屬性變化時進行通知。這是通過指派一個Bindable注解到getter方法上完成的,并且需要在setter中完成通知動作。
private static class User extends BaseObservable {
private String firstName;
private String lastName;
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getFirstName() {
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);
}
}
BR 是編譯階段生成的一個類,功能與 R.java 類似,用 @Bindable 标記過 getter 方法會在 BR 中生成一個 entry,當我們通過代碼可以看出,當資料發生變化時還是需要手動發出通知。 通過調用notifyPropertyChanged(BR.firstName)來通知系統 BR.firstName 這個 entry 的資料已經發生變化,需要更新 UI。
綁定資料
預設情況下,一個綁定類會根據布局檔案的名稱生成一個綁定類,下面代碼就是activity_main.xml生成的類ActivityMainBinding.這個類持有所有從布局檔案中的View對應的屬性(例如:user變量),并且知道如何指派變量值到綁定的表達式中。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
User user = new User("Test", "User");
binding.setUser(user);
}
官方手冊:
https://developer.android.com/tools/data-binding/guide.html