android 数据绑定(3)自动更新UI
1.官方文档
https://developer.android.com/topic/libraries/data-binding/observability
2.observable 属性
适合对象只有少量属性,每个属性用 ObservableField<xxx> 、ObservableInt、ObservableParcelable、ObservableBoolean 等保存。
基本类型 |
|
ObservableBoolean |
ObservableByte |
ObservableChar | ObservableShort |
ObservableInt | ObservableLong |
ObservableFloat |
ObservableDouble |
复杂类型 | |
ObservableParcelable |
ObservableField<非基本类型,如Student> |
ObservableArrayMap |
ObservableArrayList |
2.1 数据源类定义
1 //2.修改数据动更新ui版本 2 public class Data { 3 4 public ObservableInt icon = new ObservableInt(); 5 public ObservableField<String> key = new ObservableField(); 6 public ObservableInt value = new ObservableInt(); 7 8 @Override 9 public String toString() { 10 return "key = " + key + " value = " + value; 11 } 12 }
2.2 使用绑定
1 <TextView 2 android:id="@+id/key" 3 android:text='@{data.key, default = "default" }'/> 4 5 <TextView 6 android:id="@+id/value" 7 android:text="@{String.valueOf(data.value),default = value}" /> 8 9 <ImageView 10 android:id="@+id/imageView" 11 app:bindingImgSrc="@{data.icon}" />
2.3 修改数据源对象
1 @OnClick(R.id.btnSave) 2 public void onSaveClicked(View view){ 3 //... 4 data.key.set(newKey); 5 data.value.set(newValue); 6 7 int id = main.data.icon.get(); 8 data.icon.set(R.mipmap.girl); 9 10 }
使用get(),set(xxx) 访问和修改它们。
2.4 ObservableArrayMap
1 ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); 2 user.put("firstName", "Google"); 3 user.put("lastName", "Inc."); 4 user.put("age", 17);
使用
1 <data> 2 <import type="androidx.databinding.ObservableMap"/> 3 <variable name="user" type="ObservableMap<String, Object>"/> 4 </data> 5 … 6 <TextView 7 android:text="@{user.lastName}" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content"/> 10 <TextView 11 android:text="@{String.valueOf(1 + (Integer)user.age)}" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content"/>
2.5 ObservableArrayList
1 ObservableArrayList<Object> user = new ObservableArrayList<>(); 2 user.add("Google"); 3 user.add("Inc."); 4 user.add(17);
使用
1 <data> 2 <import type="android.databinding.ObservableList"/> 3 <import type="com.example.my.app.Fields"/> 4 <variable name="user" type="ObservableList<Object>"/> 5 </data> 6 … 7 <TextView 8 android:text='@{user[Fields.LAST_NAME]}' 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content"/> 11 <TextView 12 android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}' 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content"/>
3.自定义observable对象
- 使用@Bindable修饰get方法
- 在setter方法中使用 notifyPropertyChanged(BR.xxx);
3.1 声明数据类
1 class Daily : BaseObservable() { 2 3 @get:Bindable var week = 0 4 set(value){ 5 field = value 6 notifyPropertyChanged(BR.week) 7 } 8 9 @get:Bindable var onbed = 0L 10 set(value){ 11 field = value 12 notifyPropertyChanged(BR.onbed) 13 } 14 @get:Bindable var call = 0 15 set(value){ 16 field = value 17 notifyPropertyChanged(BR.call) 18 } 19 20 @get:Bindable var urgent = 0 21 set(value){ 22 field = value 23 notifyPropertyChanged(BR.urgent) 24 } 25 26 @get:Bindable var date = "" 27 set(value){ 28 field = value 29 notifyPropertyChanged(BR.date) 30 } 31 32 var record : List<Record> = ArrayList() 33 34 }
3.2 使用绑定数据
与2.2一样。
3.3 修改数据对象
1 @OnClick(R.id.btnSave) 2 public void onSaveClicked(View view){ 3 4 //... 5 data.setKey(newKey); 6 data.setValue(newValue); 7 8 data.setIcon(R.mipmap.girl); 9 10 }
注意:这种方式在java代码中只有调用setXXX才自动更新,data.key = "xxx"不会自动更新。
4.伴生对象成员不支持自动更新?
1 class Data(): BaseObservable() { 2 3 @get:Bindable 4 var name = "unknown_" 5 set(value) { 6 field = value 7 notifyPropertyChanged(BR.name) 8 } 9 10 companion object : BaseObservable(){ 11 @get:Bindable 12 @JvmStatic var value = 0 13 set(value) { 14 field = value 15 notifyPropertyChanged(BR.value) 16 } 17 } 18 }
Data类的伴生对象的成员value,也可以 get:Bindable ,notifyPropertyChanged(BR.value) 等声明为绑定自动通知更新,要求伴生对象的主类也要继承BaseObservable,否则编译不过。
但是实际调用后,发现并没有自动更新:
1 val checkedListener = object : CompoundButton.OnCheckedChangeListener { 2 override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) { 3 Data.value = 100 4 //binding.invalidateAll() 5 } 6 }
解决办法: 打开 第4行手动更新
<