DataBinding--Observable
DataBinding 為數(shù)據(jù)源提供了很強锌畸,很詳細的可觀察性,這就使得數(shù)據(jù)驅(qū)動UI 變的簡潔易行鹰晨,同時你可以少寫很多set(),get(),同樣也少了很多的回調(diào)
最近在學(xué)習(xí)DataBinding 的用法妹萨,發(fā)現(xiàn)確實是個十分方便的library,尤其是在MVVM 構(gòu)架中使用
在看下面的內(nèi)容前最好先對DataBinding做一個基礎(chǔ)的了解
下面對Observable做一個詳細的代碼延時
1播歼、BaseObservable
BaseObservable的使用十分簡單,會通過注解記錄需要更新的字段
集成—>加注解—>應(yīng)用完成
首先model
public class User extends BaseObservable {
//@Bindable 可以加到字段名上 也可以加載 get方法上 效果是一樣
@Bindable
public String name;
@Bindable
public String password;
public String getName() {
return name;
}
//set方法上手動調(diào)用通知數(shù)據(jù)更新掰读,此處不會自動生成
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
notifyPropertyChanged(BR.password);
}
}
布局文件xml
<!-- 數(shù)據(jù)源的聲明 -->
<!--此處聲明該xml文件要使用的數(shù)據(jù)源類型-->
<!--通過view代碼中binding.setUser()加入數(shù)據(jù) 是不是很像model -->
<!--data 數(shù)據(jù)源的聲明 要放在布局文件的根部 具體可以看DataBinding基礎(chǔ)-->
<data>
<variable
name="user"
type="com.zk.sample.module.binding.model.User" />
</data>
<!-- 數(shù)據(jù)源的使用 -->
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<!-- @={user.name} 是將當前控件的值set給指定的數(shù)據(jù)源 -->
<!-- 注意與下面的差別 @={}跟@{} -->
<EditText
android:id="@+id/et_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="用戶名"
android:text="@={user.name}" />
<!-- @{user.name} 是將當前控件的值set給指定的數(shù)據(jù)源-->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="用戶名"
android:text="@{user.name}" />
</TableRow>
View 中調(diào)用
由于做了框架抽取 binding 是父類統(tǒng)一獲取 VDB 為泛型
在Fragment 秘狞、Activity或者其他地方給XML 文件設(shè)置一個數(shù)據(jù)源
VDB binding = DataBindingUtil.inflate(inflater, getLayoutRes(), container, false);
binding.setUser(**);
到此BaseObservable 就可以演示叭莫,當你在編輯框中輸入數(shù)據(jù)時,相同數(shù)據(jù)源的展示控件就會同步顯示
2烁试、ObservableFields
ObservableFields一個類中的單獨的字段做觀察雇初,它對字段做了一層封裝,類似java中的裝箱减响;成為了一個對象級的存在靖诗,同樣使用User類來做演示。
從代碼量上來說ObservableFields的Model 要比BaseObservable少很多
model
//兩行代碼辩蛋,就是這么任性
public class UserObservable {
public final ObservableField<String> name = new ObservableField<>();
public final ObservableField<String> password = new ObservableField<>();
//ObservableField 在獲取數(shù)據(jù)的時候需要做一次調(diào)用
//如:String n = name.get()
//同理設(shè)置的時候也需要
//如:name.set("姓名");
//除了ObservableField呻畸,還有ObservableBoolean、ObservableInt ……
}
xml的使用
<data>
<variable
name="userObservable" type="com.zk.sample.module.binding.model.UserObservable"/>
</data>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<!--在此處使用的時候可以可以不做get()操作-->
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="密碼"
android:text="@={userObservable.password}" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="密碼"
android:text="@{userObservable.password}" />
</TableRow>
同BaseObservable 一樣 在View 中設(shè)置數(shù)據(jù)源悼院,之后可以看到相應(yīng)效果
3、Observable借口
對于很多model來說繼承很容易被高度限制咒循,雖然使用很簡單据途,但卻不易擴展,為此還提供了Observable 借口叙甸,跟繼承BaseObaservable 很類似
model
來看User
//相對于BaseObservable 增加了一個 回調(diào)倉庫同時也更接近通知的基礎(chǔ)
public class UserObservableImp implements Observable {
private PropertyChangeRegistry mRegistry = new PropertyChangeRegistry();
//同樣是在需要更新的字段位置加注解
@Bindable
public String name;
@Bindable
public String password;
public void setName(String name) {
this.name = name;
//在官網(wǎng)中使用的方法于此處不太一致 notifyPropertyChanged(int fieldId)
//但最終調(diào)用是一致的 其實就是做了一層基礎(chǔ)的抽取 估計都懂
//在更新數(shù)據(jù)的地方添加 通知
mRegistry.notifyChange(this, BR.name);
}
public void setPassword(String password) {
this.password = password;
mRegistry.notifyChange(this, BR.password);
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
@Override
public void addOnPropertyChangedCallback(OnPropertyChangedCallback cb) {
mRegistry.add(cb);
}
@Override
public void removeOnPropertyChangedCallback(OnPropertyChangedCallback cb) {
mRegistry.remove(cb);
}
}
xml中的使用
<!--數(shù)據(jù)源的聲明 其實都是一致的-->
<data>
<variable
name="userImp"
type="com.zk.sample.module.binding.model.UserObservableImp" />
</data>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="用戶名"
android:text="@={userImp.password}" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="用戶名"
android:text="@{userImp.password}" />
</TableRow>
數(shù)據(jù)源的設(shè)置同上
4颖医、ObservableCollection
ObservableCollection 其實就是ObservableFields 只是在調(diào)用上有一定的區(qū)別
此處用ObservableMap 做演示
model
這個沒做model 因為 我直接寫在了 View 中,跟ObservableField 是一樣的
//創(chuàng)建一個實例 設(shè)置給Binding
ObservableMap<String, String> userMap = new ObservableArrayMap<>();
userMap.put("name", "示例");
userMap.put("password", "密碼");
binding.setUserMap(userMap);
xml 中的使用
此處與上面略有不同裆蒸,主要是數(shù)據(jù)的獲取 需要指定key值
<!--數(shù)據(jù)源的聲明 有一注意事項熔萧,轉(zhuǎn)義 還有泛型-->
<import type="android.databinding.ObservableMap" />
<variable
name="userMap"
type="ObservableMap<String, String>" />
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
android:weightSum="2">
<!-- 注意引用中的標點,兩種寫的方式都可以僚祷,主要是你可以讓機器明白-->
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="密碼"
android:text='@={userMap["password"]}' />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="密碼"
android:text="@{userMap[`password`]}" />
</TableRow>
總結(jié)
到這Observable 的介紹基本完成佛致,基本上看完 也就知道怎么用了,之后還有其他內(nèi)容的演示
為此加一個連接 中文的 Databinding介紹辙谜,雖然只是個演示俺榆,但扛不住信息量大