mvvm+databinding流行了一段时间,但一直没有机会使用。最近尝试在项目中使用databinding,有一些感悟。
databinding的感悟:
集成databinding:
需要Android Studio版本>=1.3以及Android的Gradle插件版本>=1.5,在budile.gralde文件中加入:
android {
....
dataBinding {
enabled = true
// version = 1.1 // 可选,建议最好不加,使用Gradle插件默认的版本
}
}
集成看起来很简单,build发现build failed,错误信息如下:
what??只是集成了databindinng,为什么v4包会出现问题呢?
使用gradle命令"./gradlew :app:dependencies"查看项目中的依赖发现databinding的依赖如下:
从上图可以看出,databinding依赖的support-annotation是26.1.0版本,项目中support-annotation,v4,v7都是25.3.1,support-annotation的版本冲突,造成v4和v7的类也会找不到。
解决办法,强制使用databinding包下的高版本的support-annotation,在build.gradle中加入以下代码:
dependencies {
....
configurations.all{
resolutionStrategy {
force 'com.android.support:support-v4:26.1.0'
force 'com.android.support:support-v7:26.1.0'
force 'com.android.support:support_annotations:26.1.0'
}
}
}
gradle插件会帮助下载DataBinding相关的依赖包,项目中使用的gradle是3.1.3所以对于databinding库的版本也是3.1.3,但3.1.3对应的databinding下的support-annotations版本为什么是26.1.0呢?集成databinding之前需要下载支持库,感觉这个26.1.0是由sdk的Android Sdk Tools版本决定的。
注:如果是在library中使用,那么使用使用该library的module也需要在build.gradle添加,否则无法生效。
使用过程:
在Activity/Fragment/Adapter中使用bindingData方法很简单,使用方法详细参考这里。
使用databinding在xml中可以很方便的引入modle,根据modle的值设置view的显示。对于一些复杂的逻辑,点击事件等可以使用@BindingAdapter自定义属性,@BindingConversion进行显示转换,ObseravbleCollection实现更新数据。
其中在使用过程中发现几个问题:
(1)每一个布局文件都会对应一个ViewDataBinding,必须明确生成binding文件的名字,表明类型为此binding文件名,才可以调用其的属性,view,方法等。比如:比如布局名为test_data,则文件名为TestDataBinding,调用其setAdapter方法:
TestDataBinding binding = (TestDataBinding) dataBinding;
binding.setAdapter(houseAdapter);
若声明binding为ViewDataBinding,则是无setAdapter方法的,根据databinding的原理可知。
(2)在使用时,发现其中一个TextView设置
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/accent_color"
android:paddingLeft="@dimen/padding_15"
android:textSize="@dimen/textsize_16"
android:paddingTop="@dimen/padding_8"
android:text="@{data.text}"
android:visibility="@{TextUtils.isEmpty(data.text) ? View.GONE : View.VISIBLE}"/>
其中visibility不起作用,textView一直是visible状态。
(3)在Listview的adapter中使用databinding,其中Item有一个自定义view,自定义view是根据addView显示的,使用databinding后发现这个自定义view隐藏时候的item布局会显示不全。分析:看上去是listview的高度是固定的,addView显示出来的view就是显示不全未显示出来的view。
以上(2)(3)未解决,需要熟悉databinding大神指教。
使用后感触:
优点:
1、自动化绑定,直接在xml中绑定model显示页面,将数据分解到各个view上;
2、使用DataBinding后,不需要findViewById,对应adapter不需要ViewHolder,使用简单,减少对视图控制的代码量;
3、监控数据的变化,实现实时更新。
缺点:
1、ViewModel与View一一对应,每一个layout对应一个binding文件;
2、使用起来灵活性比较低,数据更新时需要双向绑定,自定义属性设置逻辑等;
3、Model属性发生变化时,ViewDatabinding采用异步更新数据,对于现实大量数据的ListView,会有一定延迟,在实践测试中发现,Databing效率较低,对于负责的界面不太适用;
4、自动生成大量代码和属性字段:ViewDataBinding 实现类 DataBinderMapper 等;
5、相关bug很难调试。
databinding原理:
参考这里