DataBinding使用记录

前言:使用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的一种体现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值