databing使用指南
簡介
隨着Android的發展,最初的MVC框架遠遠無法滿足廣大_Android猿_ 的需求,進而出現了MVP、MVVM等開發框架,Databing就是Google官方出品的支持MVVM開發的一個依賴庫。或許說依賴庫不準確,應該說是一整套開發工具和依賴庫的集合
今天我們不講開發框架的問題,我們只是來看一下 databing 的使用
簡單使用
- 在相關模塊下的
buidl.gradle
中設置對databing的支持
android {
......
//MVVM dataBinding 支持
dataBinding {
enabled = true
}
......
}
- 在
gradle.properties
中添加下面一句代碼開啓數據綁定編輯
android.databinding.enableV2=true
以上兩步完成後我們就可以開心的使用databing的方式進行編碼了。 - 代碼編寫
- 定義 ViewModel類定義 ViewModel類
public class User extends BaseObservable {
private String name;
private String sex;
private int age;
public User(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
這裏的user類和我們以前定義的實體類並沒有任何的區別。
- xml中綁定數據
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 數據元素節點,定義導入我們要綁定的數據元素 -->
<data>
<variable
name="user"
type="com.caozy.demo1.bean.User" />
</data>
<!-- 視圖元素節點 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{user.name}" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{user.sex}" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{String.valueOf(user.age)}" />
<Button
android:id="@+id/btn_1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Click Me !" />
<Button
android:id="@+id/btn_2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="btn2"
/>
</LinearLayout>
</layout>
在這裏xml文件中的根標籤不再是一個容器,而是變成了<layout></layout>
並且在頭部添加了<data></data>
標籤,和java文件中的import有類似的作用。我們一般創建的xml文件的根標籤都是容器,這裏有一個快捷鍵可以使用,將光標放在根標籤處使用快捷鍵 Mac (⌥ + Enter)
wimdows(Alt + Enter)
你會看到如下提示
選擇 Convert to data binding layout
可以很快捷的將普通的xml佈局文件轉換成 dataBinding 需要的xml形式
data binding layout 有兩部分 數據元素(即<data></data>
節點)和視圖元素
數據元素的導入方法
<variable>
標籤直接導入。
<data>
<variable
name="user"
type="com.caozy.demo1.bean.User" />
<variable
name="user2"
type="com.caozy.demo1.samename.User"/>
</data>
代碼中 name 是我們控件綁定數據時的實例引用,類似我們對java實例的應用。
type就是我們要導入的數據類型
2. 結合 <import>
標籤導入
<data>
<import type="com.caozy.demo1.bean.User" />
<!-- 取了別名的 import -->
<import type="com.caozy.demo1.samename.User"
alias="user1"
/>
<variable
name="user"
type="User" />
<variable
name="user1"
type="user1"/>
</data>
如上代碼中,如果在不同包中有同名的類,你可以在導入這個類時取一個別名,<variable>
中type用這個別名就可以了。
數據元素的綁定
佈局中使用@{}
語法在屬性中綁定數據。
android:text="@{user.name}"
這裏就是將text屬性綁定爲user的name屬性
- activity中代碼
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("張三", "男", 18);
binding.setUser(user);
}
這裏可能會有很多人奇怪ActivityMainBinding
類的由來。這個類當你將xml轉換成data binding layout 的時候就自動生成了。默認情況下生成的Binding類名是根據佈局文件名稱生成的,大寫字母開頭,移除下劃線並大寫後面的字母最後加上“Binding”後綴。Binding類位於包com.caozy.demo1.databinding.ActivityMainBinding
,當然這是在build文件夾下。也可以指定Binding類的名字,看代碼
<data class="Main"></data>
或
<data class=".Main"></data>
或
<data class="com.caozhy.Main"></data>
這裏有幾種簡單的生成規則
- 佈局中設置ID的view會在Binding類中生成 public final 變量。生成規則爲View的ID名首字母小寫,移除下劃線並大寫後面的字母。例如 tv_name會生成tvName。
- 對於layout中使用的這些綁定 當我們沒有調用
binding.setUser(user);
的時候是有默認值的。引用類型爲null,int爲0,boolean爲false等
雙向綁定
上面只是簡單的顯示一些數據,一但數據發生變化就監測不到了。別急,下面我們要講的雙向綁定就是解決這個問題的。給個栗子:
從上面的例子我們看出兩點
- 頁面上的輸入可以改變數據的值
- 數據的改變可以實時的顯示在頁面上
要實現雙向綁定在以上使用的基礎上要做以下幾點改動
- 實體類中 這裏有兩種方法
- 實體類中的成員變量或者 get方法使用
@Bindable
註解 (如下代碼中name屬性) - 或者 使用
ObservableField
定義成員變量 (如下代碼中 content 屬性)
- 實體類中的成員變量或者 get方法使用
public class User extends BaseObservable {
//使用 @Bindable 註解實現雙向綁定
@Bindable
private String name;
private String sex;
//使用 ObservableField 定義 成員變量實現雙向綁定
private ObservableField<String> content = new ObservableField<>();
public ObservableField<String> getContent() {
return content;
}
public void setContent(ObservableField<String> content) {
this.content = content;
}
//@Bindable //也可以在get方法上使用 註解
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
//更新頁面數據
notifyPropertyChanged(BR.name);
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
注意: 使用 ObservableField時有一點需要注意,定義的屬性一定要調用new ObservableField<>()
初始化
這裏對於 基本數據類型 和 list map 等都有對於的Observable類可供使用
- xml中
將@{}
改成@={}
即可
這樣就可以實現上面的例子的效果
有幾點想說:
- 如果我們只使用了
@Bindable
註解而沒有在set方法中調用notifyPropertyChanged(BR.name);
那麼上例中editText內容的改變會引起user實例name值的改變,但是不會更新頁面中textView的值。 - 我們不僅可以在user實體類的set方法中調用
notifyPropertyChanged(BR.name)
也可以在任何我們需要的地方用user類的對象調用這一方法
再給個栗子:
這裏就是將user類中的setName
方法中的notifyPropertyChanged(BR.name)
代碼去掉,Activity中添加button的點擊代碼
binding.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//更新頁面中user的name屬性
user.notifyPropertyChanged(BR.name);
}
});
- 當我們沒有用雙向綁定的時,如果user的數據發生了變化,我們也可以再次調用
binding.setUser(user);
方法更新頁面數據,每次調用binding.setUser(user);
都會進行頁面數據的更新