我都不想读概念,就一句话,数据源跟UI组件绑定。
为什么要数据源跟ui绑定呢,还不是想开发更简单么。(我们需要先监听数据的变化, 然后再将变化后的数据同步更新到UI上,这样的步骤我们一直在重复,这样的重复性代码我们写了一次又一次。而DataBinding就是为了解决这个问题而存在的,我们只需要将数据绑定到UI元素上,更新数据时UI就会跟着改变,反之亦然,大大节省了我们的代码。)
这个我们后续的博客里面会分享,这里涉及到架构的思想就先不细讲。带一句,参照前端的思想。
双向数据绑定
数据发生改变后,DataBinding会自动通知UI刷新页面,不再需要人工绑定最新数据到View上。UI改变后也能同步给数据。
减少模板代码
有了DataBinding,从此不用再写findViewById,setOnClickListener等枯燥生硬的代码,大大提高工作效率。从此ButterKnife靠边站。
释放Activity/Fragment
以前,我们在Activity,Fragment或Presenter中计算数据再绑定到View组件上,导致View层很臃肿,现在这部分工作我们可以直接在xml布局文件中完成。Activity,Fragment让它更加只关注核心业务。
数据绑定空安全
在xml中绑定数据它是空安全的,因为DataBinding在数据绑定上回自动装箱和空判断,所以大大减少了数据绑定带来的空指针问题。
1、在使用DataBinding模块的build.gradle文件中添加下面的配置
// 每个使用dataBinding的模块都应该在build.gradle中添加如下配置
android {
...
dataBinding {
enabled = true
}
}
2、在布局文件中,选中根布局的标签,按住Alt+回车键,点击 Convert to data binding layout,即可转换成DataBinding布局(见下方代码段)、
转换后的布局,最外层变成了layout标签,里面包裹了data标签和常规的布局元素。data元素用来声明在此布局用使用到的变量和变量的类型,以及类引用。
是不是所有属性都能用DataBinding来绑定呢?
当然不是!如果一个属性xxx,在该类中有setXxx方法,我们才能使用DataBinding来绑定。例如android:layout_width, android_layout_height就不能使用DataBinding来绑定数据。而android:paddingLeft, android:textSize都是可以的。
//这里可以使用variable定义多个变量,该变量需要通过外界赋值
//通过import导入需要用到的类
绑定传递数据源
给DataBinding中的User对象赋值
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//此时可以通过DataBindingUtil来设置Activity的页面布局。
//此时会返回一个ActivityMainBinding对象。这个是编译时根据xml布局文件中的数据绑定自动生成的实现类。
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
binding.user = User('张三') //完成数据绑定
//如果是在列表中使用,则可以如下编写 。ActivityMainBinding是根据activity_main布局文件自动生成的
val binding = ActivityMainBinding.inflate(layoutInflater, null, false)
binding.user = User('张三')
}
如何实现数据变化的视图自动更新呢?
DataBinding在xml中数据绑定支持的语法表达式也是非常丰富的,支付在布局文件中使用一下运算符、表达式和关键字:
如fragment_layout_mine.xml布局,在编译时会生成FragmentLayoutMineImpl.java实现类,我们可以搜索这种类debug跟进解决问题。
不建议在列表中使用,因为DataBinding数据绑定是延迟一帧的,如果列表中的ItemView的宽高需要计算后才能正确展示,不建议使用DataBinding操作。否则会看到列表ItemView明显的撑开动画,体验不好。
此处可以使用dataBinding.executePendingBindings()快速渲染布局解决
实体类配合BaseObservable可以友好的解决数据双向绑定的问题。
DataBinding经常出现在MVVM开发模式中,用以减轻Activity/Fragment的压力,可它并不是MVVM必须的一环。
我们在项目中,有时候需要用到一些公有模块,
公有模块有view 也有数据请求也有逻辑处理。
如果我们不用vm的话,我们就直接初始化公有模块,然后设置初始化参数,调用网络请求,ui设置等。
如果我们用vm的话,那么一样要先把公有的vm写一下,然后对ui部分的更新和一些小逻辑处理,我们就要在xml中处理了。
xml中import的vm可不是固定的。那怎么办呢?
这就引出 include与viewStub的使用
include 和 viewStub 的用法差不多,这里以 include 为例:
例如我们在 Activity 的 xml 布局中添加一个 include 的布局。
...
我们可以直接把 Activity 的自定义属性 testBean 传入到 include 布局中。
include_databinding_test:
这样在 include 的 xml 中能直接使用自定义属性来显示了。