1. 程式人生 > >android Data Binding 入門

android Data Binding 入門

本文參考databinding官方文件整理。官方文件連結地址https://developer.android.com/topic/libraries/data-binding/index.html#data_binding_layout_files

Data Binding框架作為官方推薦的MVVp框架已經出現很久,也越來越成熟穩定。android開發這些年從MVC到MVP,再到MVVP,開發手段不斷更新,各大公司對程式碼邏輯性要求越來越高。Data Binding作為一種主流,我們都應該抱著學習的心態瞭解它,就算我們不深入使用,也能用它來代替無聊的findViewById吧。

、工程中引入Data Binding庫

Android Studio 1.3以後,build.gradle檔案中android標籤增加以下程式碼:

android {
    ....
    dataBinding {
        enabled = true
    }
}
二、使用舉例

1、先定義一個實體類User

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;    } }
2、佈局檔案activity_main.xml中繫結User物件。此處需要注意,其實標籤變為layout,<data>標籤中定義ViewModel名字和型別。需要注意的是<variable>還能定義基本資料型別,比如String、int、boolean、Drawable等,後面會舉例使用。

<?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>
3、Activity中例項化一個User物件,繫結到佈局檔案。MainActivityBinding是databinding框架根據activity_main.xml自動生成的類。繫結成功後修改user中的欄位firstName、lastName,對應的TextView會自動同步最新資料。

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}



View按鍵事件監聽繫結

1、先定義一個Presenter類

public class Presenter {
   
    public void onSaveClick(Task tas){
	//處理按鍵點選事件
    }


    public boolean onLongClick(View view, Task task){ }


    public void onCompletedChanged(Task task, boolean completed){}


}
2、佈局檔案中繫結。此處可以看出,Data Binding支援 lambda 表示式,點選事件支援傳遞引數task。不使用lambda表示式時候可以寫成android:onClick="@{(view) -> presenter.onSaveClick(task)}"

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
      <data>
          <variable name="task" type="com.android.example.Task" />
          <variable name="presenter" type="com.android.example.Presenter" />
      </data>
      <LinearLayout 
	android:layout_width="match_parent" 
	android:layout_height="match_parent">
        	<Button android:layout_width="wrap_content" 
			android:layout_height="wrap_content"
			android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
        		android:onClick="@{() -> presenter.onSaveClick(task)}" />


 		<CheckBox android:layout_width="wrap_content" 
			  android:layout_height="wrap_content"
        		  android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />


		<Button android:layout_width="wrap_content" 
			android:layout_height="wrap_content"
        		android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}" />


      </LinearLayout>
</layout>


支援導包,通過上面兩個例子可以發現Data Binding能想java檔案一樣導包,所以我們可以匯入一些已存在的類來控制UI顯示。

1、匯入View控制可見性

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
    <import type="android.view.View"/>
<variable name="visibility" type="boolean" />
      </data>
      <LinearLayout android:layout_width="match_parent" 
   android:layout_height="match_parent">


      <TextView
  android:text="@{user.lastName}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="@{visibility ? View.VISIBLE : View.GONE}"/>


      </LinearLayout>
</layout>

2、xml檔案定義了一個名為visibility的boolean變數,使用對應的binding物件(MainActivityBinding)時候,可以MainActivityBinding.visibility設定值,對應的TextView會自動隱藏、可見。



看到這裡你可能已經發行,上面所舉栗子裡面使用到了?表示式。確實,data binding支援在xml檔案中使用表示式,利用這些表示式可以在xml檔案中處理很複雜的介面邏輯,這裡就不舉例說明,copy一份官方列舉的表示式供大家參考,大部分跟java一樣或者類似:

  • Mathematical + - / * %
  • String concatenation +
  • Logical && ||
  • Binary & | ^
  • Unary + - ! ~
  • Shift >> >>> <<
  • Comparison == > < >= <=
  • instanceof
  • Grouping ()
  • Literals - character, String, numeric, null
  • Cast
  • Method calls
  • Field access
  • Array access []
  • Ternary operator ?:


Include標籤的使用

1、bind:user為子佈局中定時的屬性名,子佈局寫法跟普通data binding佈局一樣寫法。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
   </LinearLayout>
</layout>
2、不支援include merge組合的一種使用方式

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <merge>
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
   </merge>
</layout>