Data Binding学习笔记——Data Objects
条评论关于 Data Binding 的基本使用在上一篇文章中已经做了总结,接下来会着重介绍下 Data Binding 库中个人认为最重要的两个特性:Data Objects与Attribute Setters。前者是真正能让我们实现数据-UI双向绑定的关键;后者则为我们提供了自定义 UI 控件数据绑定的可能性。
当然,至于 Data Binding 其他的特性诸如自定义Binding Class命名、Views with IDs(此特性可以完全取代Butterknife啦)等,查阅官方文档可以了。
Data Objects(数据对象)
之前介绍的基本使用中,我们定义的 model 类对象虽然能够绑定对应的 UI 并显示数据,但是修改了对象的属性并不会更新 UI。为此,Data Binding 提供了三种不同的数据变动通知机制: observable objects 、observable fields 和 observable collection 。
当以上的 observable 对象绑定在 UI 上,数据发生变化时,UI 就会同步更新。
1. observable objects
此种方法其实就是让我们定义的 model 类继承一个基类 BaseObservable ,这个类是 Observable (Data Binding 中的)接口的实现类,内部也就是基于观察者模式的一套添加/移除 listener 的机制。BaseObservable 帮我们实现了 listener 的注册,但是我们需要在 getter 使用 Bindable 注解,并在 setter 中调用方法去发通知。例子:
1 | private static class User extends BaseObservable { |
Bindable 注解会在编译时在 BR 类内生成一个元素(比如上面代码中的 BR.firstName )。
个人总结:如果一个 model 类的属性有很多,或者是想在原有项目中引入 Data Binding 的话,使用此方法的编写和改动的工作量还是有点繁琐。(不知道有没有开发者已经提供了一键生成的 AS 插件 😏)
2. observable fields
我们还可以使用 ObservableField 及它的派生比如 ObservableInt 、 ObservableBoolean 等作为 model 的数据类型。我们只要在数据类中创建一个 public final 域即可:
1 | private static class User { |
然后要存取数据的话,只需要使用 ObservableField 中的 get 、 set 方法:
1 | user.firstName.set("Google"); |
个人总结:相比第一种方法,代码编写更方便省时,缺点就是:1、数据类的 field 如果很多的话,写起来还是麻烦;2、一般我们都会用到 FastJson 配合 Retrofit 来做 API 请求,结果直接返回给我们对应直接转化好的 model 类对象,所以不太可能直接运用在原本项目中的 model 类中。参考 google 的 todo-mvvm-databinding 中可以发现,原本的 model 类还是不动,每个页面都有一个 ViewModel 类,用于存放该页面中所有的数据对象,都是 ObservableField 相关的类型。
3. observable collections
顾名思义,就是 observable 容器类,个人认为也算是上面一种。
比如使用 ObservableArrayMap :
1 | ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); |
在 xml 中,可以用 String 类型的 key 来获取 map 中的数据:
1 | <data> |
当 key 是 int 类型还可以使用 ObservableArrayList,使用的话和 ArrayList 没啥却别:
1 | ObservableArrayList<Object> user = new ObservableArrayList<>(); |
xml 中就是通过下标来获取数据,就不贴代码了 😁。
先写到这,下篇再总结Attribute Setters。