Android

Android-DataBinding使用简介

DataBinding在整个大前端算是一项很基础的技术,简单,高效,好用,有过客户端经验的都知道最开始客户端并没有支持这项技术,后来谷歌官方推出了对DataBinding的支持,大大简化了UI相关的开发成本,也推动了Android app架构从MVC向MVVM的进化,今天来介绍一波DataBinding的使用

引入DataBinding

引入很简单,在工程的build.gradle里打开databinding的开关即可

dataBinding {
        enabled = true
    }

修改布局方式

使用DataBinging之后,需要修改下传统的布局方式,整个布局改成用layout包起来

把整布局改成用layout包起来之后,在和布局同级的位置插入data标签,data标签里可以使用variable标签,类似变量的概念,引入的标签用来和正常布局绑定

布局绑定变量

在上面引入了variable标签之后,可以把variable变量和布局绑定使用

这里绑定的变量除了可以是简单的String, int这样的数据对象,也可以是java类,然后让布局直接和java类里方法做相关绑定,这类方法可以和类似点击事件做绑定

上面展示的是非静态方法的绑定,静态方法的绑定也很简单,直接在data里import了静态类,然后使用静态方法做绑定

代码端使用

前面讲了布局上databinding做啥,现在讲讲在代码层面要怎么做,首先布局肯定得inflate啊,但要使用DataBinding的方式inflate

mUserInfoBinding = DataBindingUtil.setContentView(activity, R.layout.activity_binding);

跟传统的方法不一样,inflate方法会返回一个Bingding类,这个Bingding类的对象名称我们可以在布局里对data设置name来限定

<data class="com.dbinding.jc.databindingdemo.binding.UserInfoBinding">

上面返回的binding类,对它的操作也很简单,把布局data里要使用的variable里设置进去就行

mUserInfoBinding.setUserInfo(userInfo);
mUserInfoBinding.setTitle("个人介绍");
mUserInfoBinding.setPresenter(mPresenter);

你会发现这里的设置方法setXXX是databinding框架自动生成的,如果没有的生成的话clean下工程,而方法名跟我们在布局里使用的variable是关联的,所以布局里的variable建议都是使用驼峰命名法来命名。

通过以上的简单设置我们就完成了databinding的基础使用,从此以后再也不用findViewById了,甚至连id都可以不要,UI开发起来就更快了。然后Databinding仅仅就这样吗?

双向绑定

前面我们介绍的方式只能让UI数据一次性绑定好,假设在运行过程中动态改变UI数据该怎么办呢,思路很简单,双向绑定,我都可以在代码运行过程中改变variable的值,然后UI上的展示自动跟着改变。

双向绑定的写法也很简答,需要双向绑定的数据字段我们做如下处理

如上图,继承BaseObservable,对get方法增加@Bindable 注解,set方法增加notifyPropertyChanged方法,方法里的BR是固定写法,其实这样的写法就是让DataBinding框架知道这个字段对应绑定的UI数据需要更新了。

有了双向绑定之后是不是觉得操作起来更如鱼得水了呢,但这样远远不够,有时候我们会发现我们要设置到UI上的原始数据需要做一些转换处理才能给具体的控件对象,比如图片类的url,我们直接做setBackgroundResource传入url是不支持的,这个时候要如何使用DataBinding呢?

自定义数据转换

上面提到的数据还有处理才能传给控件就要用到我们的自定义数据处理的方式,举上面的例子,图片url我们直接传给xml里的src字段是用不了的,

@BindingAdapter("listAdapter")
android:src="@{userInfo.websiteSymbol}"

我们需要利用一些开源库做另外处理,比如Glide把url解析出来,这个时候可以用BindingAdapter注解方式来告诉DataBinding框架这个xml字段需要特殊处理

public static void setImageUrl(ImageView view, String url) {
   Glide.with(view.getContext()).load(url).into(view);
}

ListView使用方式

android里有一种比较特殊的控件ListView(RecyclerView也类似),它的UI数据是循环使用的,针对这种列表循环使用的情况,databingding如何使用呢。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data class="com.dbinding.jc.databindingdemo.binding.ListDataBinding">
        <variable name="adapter" type="com.dbinding.jc.databindingdemo.adapter.ListDataAdapter"/>
    </data>
    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@+id/lv"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:divider="@null"
            app:listAdapter="@{adapter}"
            />

    </android.support.constraint.ConstraintLayout>
</layout>

先用databinding的方式绑定adapter,我们自定义了一个xml字段,listAdapter,结合前面说的BindingAdapter的方式

@BindingAdapter("listAdapter")
public static void setAdapter(ListView listView, BaseAdapter adapter) {
   listView.setAdapter(adapter);
}

在Adapter的getView方法里通过DataBindingUtil的view和bingding的转换方式来互相得到view和binding类,

 @Override
    public View getView(final int i, View convertView, ViewGroup viewGroup) {
        if(null == mList) {
            return null;
        }
        ArticleBinding articleBinding;
        if (convertView == null) {
            articleBinding = DataBindingUtil.inflate(LayoutInflater.from(this.mContext), R.layout.item_article, viewGroup, false);
            //获取convertView
            convertView = articleBinding.getRoot();
        } else {
            //通过view获取binding类
            articleBinding = DataBindingUtil.getBinding(convertView);
        }
        return convertView;
    }

经过上面这么介绍,我们可以看到DataBinding几乎考虑到了UI操作的方方面面,是一种先进的生产力,用法简单,通俗易懂,下一篇文章我们来分析分析DataBinding是如何实现的机理,里面还是有不少有趣的知识点。

今天的讲解使用的Demo事例工程在https://github.com/TChengZ/DataBindingDemo

Tagged

About chenzujie

非著名码农一枚,认真工作,快乐生活
View all posts by chenzujie →

1 thought on “Android-DataBinding使用简介

发表评论

邮箱地址不会被公开。 必填项已用*标注