新项目开发周期长,正好使用kotlin并且试水mvvm,按照网上的方法集成DataBinding,后就开始各种狗带。
1.集成
网上比较普遍的说法:
首先要增加
classpath "com.android.databinding:dataBinder:1.0-rc1"
并增加
apply plugin: 'com.android.databinding'
几乎能找到的文章都是这一个套路,然而我运行就出错
这个问题折磨了我好几个小时,然后终于在知乎发现了一篇文章
http://www.jianshu.com/p/b1df61a4df77
大意是这样的:android studio3.0之后不需要引用第一步和第二部了,google给你集成了。
所以你要做的就变成了:
第一步开启DB支持
app.gradle中android{}添加
dataBinding{
enabled = true;
}
第二步引用包
classpath "com.android.databinding:dataBinder:1.0-rc1"
因为使用了kotlin,需要在app.gradle中增加
kapt {
generateStubs = true
}
再在dependencies{}中增加
kapt "com.android.databinding:compiler:$android_version"
需注意,此处db版本要与gradle插件版本一致
然后到这里如果运行还报':app:kaptDebugKotlin'只能说明一个问题,你代码写错了,排错吧
我是先写的recyclerView代码结果一编译就报错一编译就报错,烦恼不已,后来关闭了这部分代码就可以编译通过运行了
2.使用
想要mvvm你需要做这样几件事情:
1.创建一个dataEntity,其中包括成员变量,构造函数,成员变量的get&set函数
public class userEntity { private String ea; public userEntity(String ea) { this.ea = ea; } public String getEa() { return ea; } public void setEa(String ea) { this.ea = ea; } }
2.创建一个以layout为根的layout,在第一部分使用<data/>标签声明数据源的变量
<layout xmlns:android="http://schemas.android.com/apk/res/android" > <data>
<!--引用-->
<import type="android.view.View"/>
<!--数据源--> <variable name="user" type="com.guoxd.kot.dataObserver.userEntity"/>
<!--监听-->
<variable name="listener" type="com.guoxd.kot.dataObserver.ItemClickHandler"/></ data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.ea}" />//直接调用
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@={user.eb}" />//联动赋值
<Button
android:layout_width="match_parent" android:layout_height="wrap_content"
android:visibility="@{user.checked ? View.GONE : View.VISIBLE }"//这个使用要在data中声明引入View包android :onClick= "@{(view)->listener.onButtonClick(view,user)}" />//点击内容获取是有版本限制的要注意,我用的
3.0.0-beta6允许自定义</ LinearLayout >
</layout>
3.绑定
默认情况下,一个Binding类会基于layout文件的名称而产生,将其转换为Pascal case(译注:首字母大写的命名规范)并且添加“Binding”后缀,所以一定要给组件起id。比如你的的layout文件是main_activity.xml
,因此生成的类名是MainActivityBinding
,此文件是db帮你生成的无需手动创建,如果你想自定义名字,可以在layout文件的data声明时用。此类包含从layout属性到layout的Views中所有的bindings(例如user
变量),并且它还知道如何给Binding表达式分配数值。
UserTryActivityBinding binding = DataBindingUtil.setContentView(this,R.layout.user_try_activity); userEntity user = new userEntity("01"); binding.setUser(user);
需要说明的是大部分讲解db的都是在activity中创建的,而这套方法在fragment里用不了,所以说明一下
Data binding在Activity中使用:
DataBindingUtil.setContentView(this,R.layout.activity_home);
Data binding在Fragment中使用:
DataBindingUtil.inflate(inflater,R.layout.homepage_fragment, container, false);
fragment需要返回view,返回的是声明xml的控件id:returnmBinder?.contentPanel;
Data binding在activity中或者fragment加载其他布局:
ItemMapInfoBinding infoBinding =ItemMapInfoBinding.inflate(getLayoutInflater());
View popupView = infoBinding.getRoot();
PopupWindow mPopupWindow = new PopupWindow(mContext);
mPopupWindow.setContentView(popupView);
附注说明:
我的稳定运行版本:
gradle :gradle-4.0-rc-1-all.zip
kotlin_version = '1.1.2-2' android_version = '3.0.0-alpha4'
databinding的版本决定于android_version,高于我提供的版本使用DataBindingUtil的时候要设定Bind类型
这里还有一点要说明,在给layout增加复杂数据结构时
<import type="java.lang.String"/> <import type="java.util.List"/> <variable name="lists" type="List<String>"/>//list <import type="java.util.Map"/> <variable name="maps" type="Map<String,String>"/>//map <variable name="arrays" type="String[]"/>//数组要这样写才能够通过编译