(一)
關於DataBinding
Google推出DataBinding有一段時間,但是目前來看沒有幾個人用(尷尬),當然Google推出很多東西都沒使用者(哈哈),不過作為程式猿
學習這個東西還是很有必要的,畢竟技術的革新都是在一點點試錯中發展壯大。此係列參考官方文件。
說明:
支援:Android 2.1 (API level 7+)
要求:Gradle外掛至少1.5.0-alpha1或更高,Android Studio 1.3+
構建環境
使用之前要先從Support respository下載支援包,不過現在基本上都有的,沒有support還怎麼玩。
讓後在app模組的build.gradle中新增如下:
android {
....
dataBinding {
enabled = true
}
}複製程式碼
注意:如果使用了library,而這個庫使用了databinding,主模組也要配置。
佈局檔案
databinding的佈局檔案是區別於傳統的layout檔案,跟節點是以layout開頭的,e.g.
<?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節點中定義變數名稱,type是變數的型別(全名:包名+類名)。
而使用這個變數類似:
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>複製程式碼
Data Object
上面已經寫好了佈局檔案,已經定義了user變數,下面我們就定義一個User類,
public class User {
// public final
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}複製程式碼
這樣寫的實體通常是不會變化的,就跟我們平日寫的JavaBean一樣,但是欄位必須是public和final的,還有另一種寫法
public class User {
// private final 但是有getter
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;
}
}複製程式碼
繫結資料
預設定義好了layout就會生成一個以“Binding”結尾同名的丙丁物件,讓後通過DataBindingUtil來將layout和Activity繫結。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("Test", "User");
binding.setUser(user);
}複製程式碼
- 將layout和Activity繫結
- 建立一個實體
- 將實體和佈局關聯起來
執行
上面簡單幾步,建立了一個DataBinding App現在執行起來,看看效果。
事件處理
上面只是一個簡單的示例,畢竟沒有人寫一個只做展示而沒有互動的應用,有互動必然有事件處理。DataBinding同樣可以處理這些。
- 方法引用
- 監聽繫結
方法引用
- 定義一個類
public class MyHandlers { public void onClickFriend(View view) { Toast.makeText(view.getContext(), "Hello World", Toast.LENGTH_SHORT).show(); } }複製程式碼
- 修改佈局檔案
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="handlers" type="com.example.Handlers"/> <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}" android:onClick="@{handlers::onClickFriend}"/> </LinearLayout> </layout>複製程式碼
data節點申明變數,和型別
andorid:onClick中呼叫函式, - 賦值
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); User user = new User("Test", "User"); binding.setUser(user); binding.setHandlers(new MyHandlers()); // 給變數賦值 }複製程式碼
這樣我們的時間就繫結好了,我們執行點選,就會彈出Toast。
說明:如果沒有賦值,不會報錯,也不會彈出Toast,相當於沒有繫結事件。
監聽繫結
這種方式只有在Gradle外掛version 2.0+上才能使用。
- 定義監聽類
Task表示回撥引數public class Presenter { public void onSaveClick(Task task){} }複製程式碼
- 修改layout檔案
<?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:onClick="@{() -> presenter.onSaveClick(task)}" /> </LinearLayout> </layout>複製程式碼
android:onClick=”@{() -> presenter.onSaveClick(task)}” /> 使用lambda表達試,也可以使用下面方式
android:onClick=”@{(view) -> presenter.onSaveClick(task)}”
兩種方式各有特點,根據自己需要來選擇。
(二)
上節我們講了基本使用,這節我們繼續講講已謝基本用法
說明:前期文章參考官方文件,因為基礎知識官方寫的很清楚。
導包
基本定義
上節我們使用了一下基礎導包,定義一個變數,如:
<variable
name="user"
type="com.lowett.databinding.User"/>複製程式碼
這樣寫有個問題,當有多個同樣型別的變數時候,就顯得比較麻煩了,這裡DataBinding庫提供了另一中方式
可以先導包,然後在定義變數,
<data>
<import type="android.view.View"/>
<!--匯入User-->
<import type="com.lowett.databinding.User"/>
<!--定義變數-->
<variable
name="user"
type="User"
/>
<variable
name="listner"
type="com.lowett.databinding.HandleClick"/>
</data>複製程式碼
定義別名
如果類衝突,我們還可以定義別名。
<data>
<import type="android.view.View"/>
<!--匯入User 並定義別名-->
<import type="com.lowett.databinding.User" alias="MyUser"/>
<!--定義變數-->
<variable
name="user"
type="MyUser"
/>
<variable
name="listner"
type="com.lowett.databinding.HandleClick"/>
</data>複製程式碼
範型定義
在Java中我們可以定義範型,在layout同樣可以,但是其中的括號需要特俗定義否則會報錯。
<data>
<import type="java.util.List"/>
<import type="android.view.View"/>
<!--匯入User 並定義別名-->
<import type="com.lowett.databinding.User" alias="MyUser"/>
<!--定義變數-->
<variable
name="user"
type="MyUser"
/>
<!--定義範型, 如果顯示紅色沒關係可以編譯成功-->
<variable
name="users"
type="List<MyUser>"/>
<variable
name="listner"
type="com.lowett.databinding.HandleClick"/>
</data>複製程式碼
靜態方法
匯入型別的時候我們也可匯入工具類等的靜態方法。
<data>
<import type="com.lowett.databinding.utils.Utils"/>
</data>複製程式碼
使用:
<TextView
android:layout_width="wrap_content"
android:text="@{Utils.test()}"
android:layout_height="wrap_content"/>複製程式碼
預設匯入的變數
在layout中有預設匯入幾種常用的型別,比如String,Context等,這些何以直接使用,如果顯式指定了型別將會修改掉預設的。
在layout中還有一個context變數可以直接使用。
如我們獲取螢幕尺寸:
注意:需要講int轉換為String。
這裡並沒有定義context,以及匯入String包,預設有。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.lowett.databinding.utils.Utils"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:text="@{String.valueOf(Utils.getScreenWidth(context))}"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>複製程式碼
Utils.java:
public class Utils {
public static String test() {
return "Test";
}
public static int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
}複製程式碼
自定義類名
預設的我們生成的binding類名是以佈局檔案的名字接一個Binding為字尾,我們也可以修改這個名字。
如:
<data class="MyDataClass">
</data>複製程式碼
在佈局檔案中data節點天街class屬性並定義名字,生成MyDataClass繫結物件。位於跟包名下。
如果向指定包名,那麼寫全名即可。
<data class="com.lowett.databinding.utils.MyDataClass">
</data>複製程式碼
這樣將會在com.lowett.databinding.utils下面生成繫結類。
參考官方文件。
未完待續