jetpack之数据绑定, DataBinding(二)简单沟通 observable data objects

上一篇,只是简单数据绑定,从activity向ui展示数据。

这次是能够实现双向互动的可观测的对象。可观测,是指一个对象具备的能力,它在自身数据发生变化的情况下能够通知其他对象。 Data Binding Library 允许你,让对象,对象的成员,对象集合都可以成为具有可观测的能力。

就如上一篇内提到,一个简单的plain-old object可以成为用来数据绑定,但不能自动反映到UI变化上。正如侦听器一样,我想让它一有变化立即更新到视图上。在Data Binding Library中,有三种类型我们可以选择:objectsfields, and collections.

先说简单的Field类型,直译过来是字段,直观看这个:

data>
    <import type="android.graphics.drawable.Drawable"/>
    <variable name="user" type="com.example.User"/>
    <variable name="image" type="Drawable"/>
    <variable name="note" type="String"/>
</data>

其中的note就是一个 ObservableField<String>,还有其他类型直接使用:

ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable

它是说如果你的数据类,只是些简单的数据类型,用不着去花力气实现Observable接口。 这种情况下就使用普通的Observable类型就好,上述那些具体的类,可以用作定义数据类的成员变量,作为数据对象的数据域。可观测对象域,包含了类型单一的可观测对象,语言原类型在存取过程中避免了封箱拆箱操作。如果使用这种机制来制作数据类,在java中定义 public final 添加到数据成员前面,它是只读的意思。如:

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

再说,集合对象,就是允许我们使用容器map, list 之类,如

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<String, Object>"/>
</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<Object>"/>
</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"/>

最后,说下Observable objects,它实现了 Observable 接口,允许添加或移去一个listener,使属性数据性变化时能通知到。并且,它已经实现了通知的机制,我们只关心通知的时机。为了简化开发库文件还提供了一个基类BaseObservable,现实中我只需要继承基类,然后做属性改变时的通知工作。库还提供了了@Bindable注解帮助,只要在getter()方法上实施此注解,就会在setter()方法中,调用notifyPropertyChanged() 来通知数据变化。如,

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

此处BR文件,是数据绑定库产生的,位于模块包下。通常它的条目与layout文件中data标签条目对应。如果Observable objects,对象添加了注解@Bindable其作的数据项也在编译时添加到BR文件当中。

如果遇到BaseObservable有些东西不能改变,那么Observable接口中有一个PropertyChangeRegistry 东西,可以更加有效地注册侦听器并通知它。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值