← Back to list

DataBinding系列四、数据更新

Published on: | Views: 68

对于data binding 目前已经知道 1. 将对像属性绑定到view(数据->view) 2. 将事件响应方法绑定到view(view->数据) 3. 使用绑定时运行的表达式进行小量的逻辑编写

但是,如何将对像数据的变化更新到view呢? 可以使用data binding 的setXXX方法,将对像绑定到view,但这是低效的,因为只有变化的数据才需要更新到view。对此,data binding 提供了基于观察者模式的一些方法,数据类实现这些方法后,再修改数据就会自动通知view去更新。

1.Observable Objects

可观察对像:对像中的属性变化时,更新到view,可以更新对像所有属性,也可以只更新其中一个。

方法是使对像继承BaseObservable,当数据变化时调用notifyChange或者notifyPropertyChanged函数来通知修改,data bingding就会更新数据到view,示例如下:

public class User extends BaseObservable{
    private String userName;

    //使用@Bindable注释,产生BR.XXX
    @Bindable
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
        notifyPropertyChanged(BR.userName);//通知某个变量发生了变化
    }
}
<TextView
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_marginTop="16dp"
   android:text="@{user.userName}"
   android:textSize="24sp" />

//创建一个线程来更新数据

new Thread() {
   @Override
   public void run() {
       int i = 0;
       do {
           try {
               Thread.*sleep*(2000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           user.setUserName("user " + i++);//愉快地发现不用手动发消息更新UI了
       } while (true);
   }
}.start();

如果数据类已经有其他基类了,基于java是单继承,不能使用BaseObservable类,那么可以implements Observable接口,并使用PropertyChangeRegistry来存取数据。

2.Observable Fields

可观察属性:某个属性变化时更新到view 对于这种方法,根据数据类型不同,可以使用的类为:

ObservableFields<T>

以及不需要装箱和拆箱的(可以加快速度):

ObservableBoolean, ObservableByte, ObservableChar, 
ObservableShort, ObservableInt, ObservableLong, 
ObservableFloat, ObservableDouble,ObservableParcelable

示例:

public class User {
    public ObservableField<String> name=new ObservableField<>();
}
//赋值
user.name.set("user "+count++);
//取值
user.name.get();

查看它的工作原理,发现它是对上面第一种方法的封装,只是每个类只有一个属性值:

public class ObservableField<T> extends BaseObservable implements Serializable {
    private T mValue;
    //......
    public T get() {
        return mValue;
    }
    public void set(T value) {
        if (value != mValue) {
            mValue = value;
            notifyChange();
        }
    }
}

3.Observable Collections

可观察的集合:当集合中数据变化中,自动更新到view 可使用的类为: ObservableArrayMap ObservableArrayList 示例:

public class User {
    public ObservableArrayMap<String,Object> data=new ObservableArrayMap<>();
}
<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{((ObservableMap&lt;String, Object&gt;)user.data)["sex"]}' />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{String.valueOf(((ObservableMap&lt;String, Object&gt;)user.data)["age"])}' />

//动态改变

 new Thread() {
      @Override
      public void run() {
          int count = 0;
          do {
              user.data.put("sex", "male");
              user.data.put("age", count);
              try {
                  Thread.sleep(2000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          } while (mRun);
      }
  }.start();

这两个类也是封装第一种方法实现。