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