databinding是Google推出的一款可以把视图和数据源直接绑定的依赖库。这篇文章只是介绍databinding的使用,和MVVM并没有什么关系。
一、导入依赖
在app的build.gradle中导入依赖。
implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0'
并且在android{}中开启databinding
android{
dataBinding {
enabled = true
}
}
二、使用方法
1.创建AClass类
使用Observable来对xml进行绑定
public class AClass {
public ObservableField<String> text= new ObservableField<>("");
}
当xml引用AClass 后,AClass中的属性数据变化就会引起引用对应属性的xml显示变化,同样,xml有响应时也会对应AClass中属性的变化,从而实现双向绑定。
2.创建activity_demo.xml
以<layout></layout>为根标签,<data></data>为模型创建xml,示例:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="com.example.demo.AClass" />
<variable
name="aClass"
type="AClass" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@={aClass.text}"/>
</LinearLayout>
</layout>
需要注意的是:<layout></layout>标签不能有宽高
创建好xml之后会自动生成对应的BR文件,就像R文件一样。
3.创建DemoActivity
Activity中需要初始化databinding
public class DemoActivity extends AppCompatActivity {
protected ActivityDemoBinding mDataBinding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initAAC();
}
/**
* 初始化AAC组件
*/
private void initAAC() {
mDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_demo);
SparseArray<Object> variableSA = new SparseArray<>();
variableSA.put(BR.aClass, CastUtil.cast(new AClass()));
if (variableSA != null && variableSA.size() > 0) {
for (int i = 0; i < variableSA.size(); ++i) {
final int variableId = variableSA.keyAt(i);
final Object variableValue = variableSA.valueAt(i);
mDataBinding.setVariable(variableId, variableValue);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁DataBinding
if (mDataBinding != null) {
mDataBinding.unbind();
}
}
}
4.用到一个工具类CastUtil
public class CastUtil {
/**
* 用于消除类型装换警告
* @param obj 原类型数据
* @param <T> 泛型
* @return 装换类型后的数据
*/
@SuppressWarnings("unchecked")
public static <T> T cast(Object obj) {
return (T) obj;
}
}
以上就完成了databinding双向绑定。
三、xml中databinding的写法
databinding在xml中的用法有很多,我也只是用过几种。想到的就先记录一下,剩下的之后想到了再补充。
1.给控件设置文本:
android:text="@={aClass.text}"
public ObservableField<String> text= new ObservableField<>("Hello World");
2.给控件设置点击事件:
android:onClick="@{aClass.click}"
public View.OnClickListener click=v -> {
//点击的操作
text.set("你好,世界");
};
3.给控件设置显示隐藏
(1)<data></data>中添加View包,控件可以使用三元运算符android:visibility='@{aClass.visibility?View.VISIBLE:View.GONE}'
<!-- 放在data标签里 -->
<import type="android.view.View" />
<!-- 放在需要操作的控件里 -->
android:visibility='@{aClass.visibility?View.VISIBLE:View.GONE}'
(2)直接设置ObservableInt
android:visibility='@{aClass.visibility}'
public ObservableInt visibility = new ObservableInt(View.VISIBLE);
4.给控件设置drawable
正常情况下的shape直接设置就好,有种情况是drawable随着条件不同会动态变化。
android:drawable='@{aClass.status?@drawable/shape_1:@drawable/shape_2}'
这样就可以依靠status的改变而改变样式了。
唯一需要注意的一点就是现在databinding中不支持mipmap中文件的引用。如果想引用图片的话,还是放在drawable文件夹下吧。
还有许多许多用法,一时想不起来那么多,也没用过那么多,以后有机会再补充吧。
四、自定义属性
有些时候,可能会无法满足需求,这个时候就需要去自己定义自己想要的属性了。比如直接给ImageView设置网络图片地址的时候。
@BindingAdapter(value = "imageUrl", requireAll = false)
public static void setSrc(ImageView imageView, String url) {
Glide.with(imageView.getContext()).load(url)
.into(imageView);
}
这样就可以用imageUrl来设置网络图片了。
<ImageView
imageUrl="@{aClass.url}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
public ObservableField<String> url= new ObservableField("");