前言:使用DataBinding最直观的好处可以代替findViewbyId,另外配合MVVM使用也是非常方便的。
如何使用DataBinding替代我们通常写的findViewbyId?
在使用之前我们先要关联DataBinding库;
在项目app目录下面的build.gradle文件中的android节点添加如下配置:
dataBinding { enabled = true }
然后重新build一下项目即可。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<include
android:id="@+id/toolbar_layout"
layout="@layout/toolbar" />
<com.xxx.widget.SuperSwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:overScrollMode="never" />
</com.xxx.widget.SuperSwipeRefreshLayout>
</LinearLayout>
</layout>
上面的布局跟平常使用的布局有一点不同就是多了最外层的layout节点;
这时,回到该布局所在的Activity中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.inflate(
LayoutInflater.from(this)
, R.layout.activity_collect_list, null
, false);
setContentView(mBinding.getRoot());
initView();
initData();
}
利用DataBindingUtil绑定整个布局,现在当你需要获取布局中的View对象不再使用findViewById方法了;
private void initView() {
collectListAdapter = new CollectListAdapter(this);
mBinding.listView.setAdapter(collectListAdapter);
mBinding.swipeRefresh.setOnPullRefreshListener(xxx);
mBinding.swipeRefresh.setOnLoadMoreListener(xxx);
}
可以看到直接利用mBinding对象找到自身中的属性(View对象)就直接可以操作了。
在MVVM中使用DataBinding
首先来看一个布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable name="viewModel"
type="com.xxx.CollectListItemNewsViewModel" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15.0dip"
android:paddingRight="15.0dip"
android:paddingTop="10.0dip"
android:paddingBottom="5dp"
android:onClick="@{viewModel.onClickListener}"
android:background="@drawable/selector_item_bg">
<TextView
android:id="@+id/collect_list_title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:maxLines="2"
android:text="@{viewModel.title}"
android:textSize="15sp"
tools:text="title"
android:textColor="@color/text_color_title"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dip"
android:layout_below="@id/collect_list_title"
android:gravity="center_vertical"
>
<TextView
android:id="@+id/collect_content_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginRight="5dip"
android:background=
"@drawable/collect_item_flag"
android:text="@string/news"
android:textSize="12sp"
android:textColor="#DD2222" />
<TextView
android:id="@+id/collect_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.collectTime}"
android:textColor="@color/collect_tv_des_time"/>
</LinearLayout>
</RelativeLayout>
</layout>
我们在布局中通过下面的配置导入了CollectListItemNewsViewModel类
<data>
<import type="android.view.View" />
<variable name="viewModel"
type="com.xxx.CollectListItemNewsViewModel" />
</data>
又通过类似下面的配置利用CollectListItemNewsViewModel类的属性给控件赋值
android:text="@{viewModel.collectTime}"
这里涉及到MVVM模式,M代表Model也就是JavaBean,V代表View是我们的布局,VM是ViewModel就是布局中绑定的CollectListItemNewsViewModel类;
现在我们看一下在Activity中的java代码:
binding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.item_collect_list_news, parent, false);
CollectListItemNewsViewModel viewModel = new CollectListItemNewsViewModel(mActivity);
binding.setViewModel(viewModel);
binding.getViewModel().renderView(item);
// item既是前面说的JavaBean类对象
实际上是item_collect_list_news布局中绑定的CollectListItemNewsViewModel 类渲染View数据的逻辑;
CollectListItemNewsViewModel .java参考代码如下:
@BindingView(R.layout.item_collect_list_news)
public class CollectListItemNewsViewModel {
protected final Activity mActivity;
protected ObservableField<String> mTitle
= new ObservableField<>();
protected ObservableField<String> mCollectTime
= new ObservableField<>();
protected View.OnClickListener mOnClickListener;
public CollectListItemNewsViewModel(Activity mActivity) {
this.mActivity = mActivity;
}
public ObservableField<String> getTitle() {
return mTitle;
}
public ObservableField<String> getCollectTime() {
return mCollectTime;
}
public View.OnClickListener getOnClickListener() {
return mOnClickListener;
}
public void renderView(RspCollectList.DataBean collectItem) {
if (collectItem == null) {
return;
}
mTitle.set(collectItem.getTitle());
mCollectTime.set(collectItem.getFavorited_at());
mOnClickListener = v -> {
Intent intent = new Intent(mActivity, ArticleWebActivity.class);
intent.putExtra(ArticleWebActivity.KEY_CONTENT_ID, collectItem.getContent_id());
mActivity.startActivity(intent);
};
}
}
这样就实现了data和view之间的绑定了,这也是MVVM的一种体现。