android Data Binding 数据变化监听

本文参考databinding官方文档整理。官方文档链接地址https://developer.Android.com/topic/libraries/data-binding/index.html#data_binding_layout_files

Data Objects


Any plain old Java object (POJO) may be used for data binding, but modifying a POJO will not cause the UI to update. The real power of data binding can be used by giving your data objects the ability to notify when data changes. There are three different data change notification mechanisms,Observable objectsobservable fields, and observable collections.

When one of these observable data object is bound to the UI and a property of the data object changes, the UI will be updated automatically.

以上文字引用自官方文档,大致意思就是传统的java对象都可以用于data binding,但是修改一个被绑定的对象并不能保证它能成功通知UI刷新,所有官方给出来三种方式来解决这个问题,确保一个被绑定的对象发生变化时能保证对应的UI做出相应变化。三种方式分别为Observable objects, observable fields, and observable collections。


第一种方式Observable objects

让对象继承BaseObservable,在需要刷UI的字段被改变时通知监听着变化,举例如下:

private static class User extends BaseObservable {
   private String firstName;
   private String lastName;
   @Bindable
   public String getFirstName() {
       return this.firstName;
   }
   @Bindable
   public String getLastName() {
       return this.lastName;
   }
   public void setFirstName(String firstName) {
       this.firstName = firstName;
       notifyPropertyChanged(BR.firstName);
   }
   public void setLastName(String lastName) {
       this.lastName = lastName;
       notifyPropertyChanged(BR.lastName);
   }
}
firstName和lastName被赋值时候调用了notifyPropertyChanged通知监听者做出对应变化,个人认为这种方式的好处是可以控制那些字段的更新需要通知UI变化;缺点时java的单一继承使得此类不能有其它父类。

第二种方式observable fields

使用ObservableField来定义那些需要通知UI变化的字段,字段值改变后观察者能及时收到数据改变的通知,举例如下:


private static class User {
   public final ObservableField<String> firstName =
       new ObservableField<>();
   public final ObservableField<String> lastName =
       new ObservableField<>();
   public final ObservableInt age = new ObservableInt();
}
使用举例如下:
user.firstName.set("Google");
int age = user.age.get()

这种方式保留了第一种方式的灵活性,同时解决了第一种方式中存在的单一继承问题。


第三种方式 observable collections

使用监听者集合。将字段添加到一个集合中,使用时候根据key获取到对应值,集合中字段变化时候也能通知到监听者。举例如下:

定义一个ObservableArrayMap集合

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);
布局中使用

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap&lt;String, Object&gt;"/>
</data><TextView
   android:text='@{user["lastName"]}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user["age"])}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>


定义一个ObservableArrayList

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);
布局中使用

<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList&lt;Object&gt;"/>
</data><TextView
   android:text='@{user[Fields.LAST_NAME]}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

这种方式存在数据兼容问题,如果定义数据类型为object,存在大量的数据转换,效率不高。


最后,虽然谷歌给出多种方式来实现数据通知,但是实际使用过程中android:text="@{user.lastName}"暂未见到数据改变,UI不更新的问题,这也许跟本人的使用深度有关系。同样,android:text="@={user.lastName}"实现双向绑定时候也未发现UI数据变化后,user中对应字段未更新的情况。


猜你喜欢

转载自blog.csdn.net/qi15211/article/details/72729697