天天看點

Android Data Binding 技術

       Data Binding

       Data Binding即資料綁定,Data Binding 庫實作在布局檔案中實作資料綁定申明,使資料的變化引起視圖的自動更新,減少了邏輯代碼,在Android中可以很友善的實作MVVM的開發模式。

       MVVM

       了解MVVM之前,我們先簡單說一下MVC、MVP模式。

       MVC是Model(模型)---View(視圖)---(Controller)控制器的縮寫,它用一種将業務邏輯、資料、界面顯示分離的方法組織代碼,将業務邏輯聚集到一個部件裡面,在改進和個性化定制界面及使用者互動的同時,不需要重新編寫業務邏輯。将系統進行MVC分層的核心思路就是分離元件,降低元件耦合性,元件獨立演化。

Android Data Binding 技術

       MVP是Model--View--Presenter的縮寫,MVP與MVC的主要差別是在MVP中View并不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進行的,所有的互動都發生在Presenter内部,而在MVC中View會從直接Model中讀取資料而不是通過 Controller。模型與視圖完全分離,我們可以修改視圖而不影響模型,可以更高效地使用模型,因為所有的互動在Presenter裡面。

Android Data Binding 技術

       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來寫。

Android Data Binding 技術

      環境搭建

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

繼續閱讀