参考文章:https://www.jianshu.com/p/ba4982be30f8
环境配置
在gradle里添加对dataBinding的支持:
android{
...
dataBinding{
enable = true
}
}
安装插件:Databinding Support对layout文件支持,Data Binding Formatter对class文件支持
使用
编写布局文件,使用变量:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.example.Article"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.title}"
android:textSize="@dimen/base_font_size_large_18"
android:textStyle="bold"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.view+`次浏览`}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.like+`个喜欢`}"
android:layout_marginLeft="10dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:value="@={viewModel.reader}"/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:bindSrcToImage="@{viewModel.image}"
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已阅"
android:onClick="@{viewModel::onClickRead}"/>
</LinearLayout>
</layout>
在layout文件中使用Article对象,要想把Article对象的相关字段绑定在UI上,还需要申明这些字段是“可观察的”,可以这样实现:
- 继承BaseObservable,然后用@Bindable注解需要观察的属性
- 使用ObseravbleField类型包裹属性
Android studio会根据layout文件自动生成一个默认的Binding类,类名是根据layout文件名生成的,并有"Binding"后缀结束。例如:activity_article.xml生成的Binding类为ActivityArticleBinding,可用如下方式使用Binding类:
ActivityArticleBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_article);
Article article = new Article();
binding.setViewModel(article);
或者:
ActivityArticleBinding binding = ActivityArticleBinding.inflate(getLayoutInflater());
在RecyclerView的adapter中的item里使用DataBinding:
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
//or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
在layout中绑定的onClickRead方法只需要在Article中实现一个public的onClickRead方法即可
在layout中申明的bindSrcToImage属性需要加@BindingAdapter注解实现逻辑,如:
@BindingAdapter("bind:bindSrcToImage")
public static void setSrcToImage(ImageView imageView,String src){
Glide.with(mContext).load(src).into(imageView);
}
使用同样方法可以覆盖控件的原set方法实现,且可以同时处理多个属性,如:
@BindingAdapter({"android:onClick", "android:clickable"})
public static void setOnClick(View view, View.OnClickListener clickListener,
boolean clickable) {
view.setOnClickListener(clickListener);
view.setClickable(clickable);
}
使用import标签导入类,然后可以使用类的静态资源:
<data>
<import type="android.view.View"/>
</data>
<TextView
android:text="@{article.content}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{article.isFold ? View.VISIBLE : View.GONE}"/>
- 有时候我们可能不知道Binding类的名称,比如RecyclerView.Adapter中item布局可能有很多,并不会对应特定的Binding类,但是仍然需要通过onBindViewHolder(VH, int)去绑定数据,下面的例子是,所有的子布局都有一个"item"变量(所有申明的变量都在BR文件里面),通过ViewDataBinding基类去完成绑定:
public void onBindViewHolder(BindingHolder holder, int position) {
final T item = mItems.get(position);
holder.getBinding().setVariable(BR.item, item);
holder.getBinding().executePendingBindings();
}
- 有时候我们需要自定义属性变化的业务逻辑,我们可以给Observable变量设置变化监听:
ObservableInt flag = new ObservableInt();
flag.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if(sender.get() == 0){
finish();
}
}
});
- 有时候我们想要在类里面申明的数据类型和layout里面使用的数据类型不一样,那我们可以使用@BindingConversion注解实现,比如将整型颜色值转化为Drawable:
@BindingConversion
public static ColorDrawable convertColorToDrawable(int color) {
return new ColorDrawable(color);
}
写于2018-4-25









网友评论