实战
首先看一下之前代码
public class Goods {
public String name;
public String details;
public float price;
public Goods(String name, String details, float price) {
this.name = name;
this.details = details;
this.price = price;
}
}
非常简单的Goods 类,只有几个属性。如果有一种情况,如果Goods 的name在设置了之后,又发生了变化,我需要更新显示的name的View,怎么办?
这样的代码已经达不到我们需要的效果,所以我要借助DataBinding中的BaseObservable接口。
public class Goods extends BaseObservable {
//如果是 public 修饰符,则可以直接在成员变量上方加上 @Bindable 注解
@Bindable
public String name;
//如果是 private 修饰符,则在成员变量的 get 方法上添加 @Bindable 注解
private String details;
private float price;
public Goods(String name, String details, float price) {
this.name = name;
this.details = details;
this.price = price;
}
public void setName(String name) {
this.name = name;
//只更新本字段
notifyPropertyChanged(com.lisn.mywanandroid.BR.name);
}
@Bindable
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
//更新所有字段
notifyChange();
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
从上面的代码看出,集成了BaseObservable接口之后,出现了三个新的方法:
notifyChange() :对象已经发生改变,所有绑定过该对象的view都需要刷新。
notifyPropertyChanged(BR.name) : 对象的某一个属性发生了改变,通过使用了这个属性的view进行更新。
@Bindable : 把某一个对象的属性绑定到BR文件中,代码中对name进行了绑定,所以在BR中就出现了BR.name, 来直接找到这个属性。
这样就已经达到了我们想要的效果,其实DataBingding除了提供了可见接口来帮助我们实现这种效果,还提供了可见字段:
ObservableBoolean, ObservableByte, ObservableChar 等基本数据类型,还包括对象类型ObservableField等。
可见字段是独立字段的可见对象,原始版本在访问操作中避免装箱和拆箱,为方便使用,在数据类创建中使用 pulic 。
下面来再次修改Goods 的代码:
public class ObservableGoods {
public ObservableField<String> name;
public ObservableFloat price;
public ObservableField<String> details;
public ObservableGoods(String name, float price, String details) {
this.name = new ObservableField<>(name);
this.price = new ObservableFloat(price);
this.details = new ObservableField<>(details);
}
}
非常的简洁,看上去应该是对基本类型进行了一次包装,使用起来非常简便。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{observableGoods.price+"",default=price}'
android:textAllCaps="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{observableGoods.details,default=details}"
android:textAllCaps="false" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->observableGoodsHandler.changeGoodsName()}"
android:text="setName"
android:textAllCaps="false" />
使用中直接给observableGoods中name通过set方法设置值,对应的UI页面也马上自动更新,还可以通过成员变量的get()方法获取属性值。 observableGoods.name.set("newName");
字符串拼接:
android:text='@{observableGoods.price+"",default=price}' 注意是单引号,汉字可以使用@string.name定义
可见集合
在提供了基本字段以外,还提供了可见集合:
ObservableArrayMap和ObservableArrayList。
使用方法:
<data class="TestDataBinding2">
<import type="android.databinding.ObservableList" />
<import type="android.databinding.ObservableMap" />
<variable
name="observableMap"
type="ObservableMap<String,Object>" />
<variable
name="observableList"
type="ObservableList<Object>" />
<variable
name="key"
type="String"/>
</data>
注意转义符 < 代表 < > 代表 >
type="ObservableList<Object>" 等于 type="ObservableList<Object>"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{observableMap["name"],default=observableMap}' />
<!--android:text='@{observableMap[key],default=observableMap}' />-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{observableList[0],default=observableList1}' />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{observableList[2],default=observableList2}' />
TestDataBinding2 mBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding2);
......
ObservableList<Object> observableList = new ObservableArrayList<>();
observableList.add("name1");
observableList.add("name2");
observableList.add("name3");
observableList.add("name4");
mBinding.setObservableList(observableList);
mBinding.setKey("name");
ObservableArrayMap<String, Object> observableMap = new ObservableArrayMap<String, Object>();
observableMap.put("name", "hahahaha");
observableMap.put("detail", "aaaaaaaa");
mBinding.setObservableMap(observableMap);