前言
BaseObservable
ObservableField
ObservableCollection
在学习DataBinding后,我们使用它绑定控件后,每次改变数值,都要向DataBinding传值进行更新后才能刷新UI,这时我们就要使用单向绑定实现自动刷新UI。
使用单向绑定刷新UI的方式有三种
BaseObservable提供了两个刷新UI的方法,分别是
notifyPropertyChanged(); 只会刷新属于它的UI,对应BR的数据
notifyChange(); 会刷新所有UI。
public class Good extends BaseObservable {
public String name;
private String detail;
private float price;
public Good(String name,String detail,float price) {
this.detail = detail;
this.name = name;
this.price = price;
}
public float getPrice() {
return price;
}
@Bindable
public String getDetail() {
return detail;
}
@Bindable
public String getName() {
return name;
}
public void setDetail(String detail) {
this.detail = detail;
notifyChange();
}
public void setName(String name) {
this.name = name;
//此处可以简写为BR.name但是name会标红,不会出现编译错误
notifyPropertyChanged(com.example.mvvmthree.BR.name);
}
public void setPrice(float price) {
this.price = price;
}
}
在MainActivity中定义改变类,说明改变规则,为了更好的理解notifyPropertyChanged() 和 notifyChange() 的区别,在改变规则中我都加了对price的改变
对layout布局中在onClick中规定改变规则,格式为@{ }
layout具体实现如下:android:textAllCaps = false 只是为了使显示的文字小写
和上一节DataBinding(一)所学相似,初始化对象赋值即可
当我们点击改变属性name 和price按钮时,只由name发生了改变,而点击另一个按钮时,两个属性都发生了改变,这就是notifyPropertyChanged() 和 notifyChange() 的区别的体现。
我们可以通过addOnPropertyChangedCallback方法查看哪些数据发生了改变
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
good = new Good("火龙果","好吃不贵",24);
mainBinding.setGood(good);
mainBinding.setGoodsHandler(new GoodHandler());
good.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (propertyId == com.example.mvvmthree.BR.name) {
Log.e("MAIN", "BR.name");
} else if (propertyId == com.example.mvvmthree.BR.detail) {
Log.e("MAIN", "BR.details");
} else if (propertyId == com.example.mvvmthree.BR._all) {
Log.e("MAIN", "BR._all");
} else {
Log.e("MAIN", "未知");
}
}
});
}
查看代码
ObservableField实际上是对BaseObservable的进一步封装,可以不需要再使用注解,与BaseObservable的用法相差不大,只是再自定义类的创建以及使用时有所不同,再自定义类中的变量类型改为如下形式:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableField< 泛型>
注意:在ObservableField提供了get、set方法,可以拿到值和更新值来达到更新UI效果,一般在类中的变量多用public final修饰,无法书写Set方法,而且即便是写了Set方法也无法对值进行修改,只有通过ObservableField提供的set方法才能修改值。
public class ObservableGood {
private ObservableField name;
private ObservableField details;
private ObservableFloat prices;
public ObservableGood(ObservableField name,ObservableField details,ObservableFloat prices) {
this.details = details;
this.name = name;
this.prices = prices;
}
public ObservableField getDetails() {
return details;
}
public ObservableFloat getPrices() {
return prices;
}
public ObservableField getName() {
return name;
}
}
在此时定义的变化类内部的方法会使对应数据和布局发生改变。
layout的具体实现:
最后同样进行初始化和赋值即可
public class MainActivity extends AppCompatActivity {
private ObservableGood good;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
good = new ObservableGood(new ObservableField("jerry"),new ObservableField("beta"),new ObservableFloat(90));
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setGood(good);
binding.setListener(new Listener());
}
···
}
当我们的使用对象改为Map或者List形式时,DataBinding提供了 ObservableMap 和 ObservableList可供使用,我们可以直接导入包,直接使用。
(1)ObservableList的使用
首先应引入,并声明数据类型
在写布局时,应注意此时Text View中Text属性使用单引号。
初始化List,并显示布局
更新UI的方法与上面介绍的方法相同:声明新的变化类,并引用
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private ObservableList list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
list = new ObservableArrayList<>();
list.add("study");
list.add("work");
list.add("up");
binding.setList(list);
binding.setUpdata(new Updata());
}
public class Updata{
public void change() {
for (int i = 0;i < list.size();i ++) {
list.set(i,"以改变" + i);
}
}
}
}
在layout中引用:注意ObservableList类型的书写,ObservableList < 元素类型 >
效果图:
查看代码
( 2 )ObservableMap的使用
ObservableMap < key类型,对应数据类型>
同样的初始化并赋值
自动更新UI与上面所学形式相同,此处不在举例。
代码