DataBinding(五)自动更新

2018-03-22  本文已影响0人  timshinlee

虽然使用普通的Java对象就可以把数据绑定到UI界面,但是当数据变动时,UI却不会及时更新,所以DataBinding提供了observable objects、observable fields、observable collections来达到自动更新的效果。

observable objects

如果一个类实现了android.databinding.Observable接口,则DataBinding会绑定一个监听器来监听这个类的属性变化,DataBinding为了方便我们使用,提供了一个实现类BaseObservable。BaseObservable接口帮我们进行了监听器的绑定和移除,我们只要自己进行更新就可以了。对于getter使用@Bindable注解来生成BR.propertName字段,然后setter中调用notifyPropertyChanged(BR.propertName)语句来通知更新。

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);
   }
}

observable fields

对于自定义类可以通过以上方式进行设置,同时DataBinding也提供了另一种比较简便的方式,可以对单一字段进行包装,自动更新该字段:

private static class User {
   public final ObservableField<String> firstName = new ObservableField<>();
   public final ObservableField<String> lastName = new ObservableField<>();
   public final ObservableInt age = new ObservableInt();
}

其他可以使用的包装类包括:ObservableBoolean、ObservableByte、ObservableChar、ObservableShort、ObservableLong、ObservableFloat、ObservableDouble、ObservableParcelable。

赋值及取值使用set和get方法:

user.firstName.set("Google");
int age = user.age.get();

ObservableField还有另一种用法,即通过<include />传递属性,传递的属性是ObservableField<String>,然后被include的文件中使用String接收。
例如:

<layout>
    <data>
       <variable
           name="user"
           type="com.example.testdatabinding2.User"/>
    </data> 
     <include
            layout="@layout/extra"
            app:firstName="@{user.firstName}"/>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable
            name="firstName"
            type="String"/>
    </data>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{firstName}"/>
    </LinearLayout>
</layout>

observable collections

当使用了集合数据时,如果key是引用类型,可以使用ObservableArrayMap包装类:

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

<!-- XML -->
<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"/>

如果key是int类型,则可以使用ObservableArrayList包装类:

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

<!-- XML -->
<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"/>
上一篇下一篇

猜你喜欢

热点阅读