为什么我们需要Data Binding
传统的MVC模式如下图所示:
这种模式的初衷是让业务逻辑和View分开,让我们在修改界面而不改变业务逻辑的时候更简单,但是实习操作的时候往往很难完全对View和Controller或Model很好的分离。并且三种组件也增加了一定的复杂度。而当我们有了Data Binding技术我们就可以使用另外一种模式(这种模式常用于Windows软件开发)叫MVVM 全称是Model-View-ViewModel,Model代表的是你的业务逻辑,View是展示的视图,ViewModel是把二者绑定起来的接口。这样说还是有点抽象,在一般Android开发里,如果某个View展示的数据出现了变化,我们需要findViewById找到这个View,并且设置新更新的数值。而在MVVC里,因为Model和View是绑定的,如果model层的数据发送了变化,会自动通知更新view应该如何重新变化展示。听起来是不是非常棒哈。
如何在Android里使用
- 准备环境
在整个工程里的build.gradle里添加如下依赖:
在你需要的使用data binding的module对应的build.gradle里添加
apply plugin: 'com.android.databinding'
ps:这里需要Android Studio是1.3以上,gradle版本在1.3以上,我之前即使是这样设置了还是有问题,我把build tool还有兼容包全部升级到最新版本就木有问题了。
下面我将已一个例子来介绍Android的DataBinding,这个小程序叫MagicNumber,app里显示一个数从1开始,有一个按钮,按一次按钮数字加1,若数字是奇数数字将显示黄色,若是偶数显示蓝色。
先写布局:
注意如下变化:布局文件里的根元素不再是ViewGroup而是一个叫layout的标签,这个标签里包含一个data标签还有一个View,data标签里面包含了要绑定的数据元素类型申明等信息。在本例子里,我们要绑定的数据类型叫MagicNumber,然后在布局里它的名字叫num,type是这个类的完整路径名(若是Java自带的类型直接写就好,比如String,int)。在其他地方若要用到这个绑定数据的值只需要用@ {obj.xxxx}就行。这里要注意一个问题,就是在访问obj的成员变量的时候不一定总是它的全名,我试了一下我的MagicNumber里有一个成员变量叫isOdd,但是要访问它的话我要这样写 @{num.odd}。在这里还可以使用一些语句来实现简单的逻辑操作,比如我在布局文件里写入了奇偶不同颜色不同的逻辑。在textView里
android:textColor="@{num.odd ? @color/light_yellow : @color/light_blue}"
带Observable模式的MagicNumber类
Observable模式就是,当绑定的数据发送变化的时候,这个绑定的View会自己更新显示信息。这里可以使用MagicNumber继承一个叫BaseObservable的类来实现。(也可以使用ObservableField来实现对某一个field的Observe而不用继承)。
这里要注意,需要有更新通知功能的成员变量的get方法里,添加@Bindable这个注解,然后在起更新数据的地方调用对应的notifyPropertyChanged(BR.xxx)。在本程序里是如果MagicNumber调用了addOne就通知数据更新。
(注:BR 是编译阶段生成的一个类,功能与 R.java 类似,用 @Bindable 标记过 getter 方法会在 BR 中生成一个 entry,当我们通过代码可以看出,当数据发生变化时还是需要手动发出通知。)
好了,终于到了最后真正实现绑定的一步了!
注意,这里不再使用setContentView(),使用的DataBindingUtil.setContentView()返回一个binding,用它来绑定数据。(这里的set方法是更具之前data里写入的type动态生成的)。
还有一个更好用的特性,若你在布局文件里给了某个View一个ID,在Activity里你想要使用这个View你不再需要些findViewById,你只需要从前面绑定产生的那个binding.xxxx (xxx是view的id名)就可以直接对这个View进行操作了!Awesome!
参考: Google官方guide