学习自Google文档以及大帅的博客,文末地址链接。

1. DataBinding

自从Google加入了DataBing,还是很受开发者喜爱的,所以,咱也来学习下DataBinding是什么鬼东西。

在gradle文件的android节点下。添加如下配置,就开启了DataBinding。

dataBinding {
        enabled = true
    }

下面有几点说明:

  • 下文所有代码均在Android Studio 2.2 上
  • Jack编译链暂不支持DataBinding
  • 编译器智能提示还是有点弱鸡
  • 遇到报红,别慌
  • 等等

2. DataBinding尝鲜

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
>
    <data class="CustomLayout">
        <variable
            name="user"
            type="beans.User"/>
        <variable
            name="handler"
            type="events.SaveHandler"/>
    </data>
    <LinearLayout
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.username}"
            android:onClick="@{()->handler.saveUser(user)}"
            />
    </LinearLayout>
</layout>
  • layout下包含两部分内容
  • 对应数据部分
  • 声明的变量
  • 布局部分
  • @{} 的形式去用声明的变量

在我们对应的Activity下,修改代码如下

CustomLayout layoutBinding = DataBindingUtil.setContentView(this,R.layout.custom_activity);
User user = new User("custom");
layoutBinding.setVariable(BR.user,user);

而其中对应的CustomLayout是什么呢?这是我在这里自定义的DataBingding的类名,是在xml中data部分通过class属性指定的。如果我们没有指定,就会按照布局文件名去生成,如activity_main.xml生成的就是ActivityMainBinding。关于自定义对应DataBinding类名 

就这样,我们就完成了数据的绑定。不要停,我们继续来看事件的绑定

3.事件的绑定。

事件绑定分为两种

  • 方法引用
  • 监听事件
3.1 方法引用

先声明接口。

public interface ClickHandler {
    public void onClickTest(View view);
}

然后在Activity里实现接口。

@Override
    public void onClickTest(View view) {
//        Snackbar.make(view, "click", Snackbar.LENGTH_LONG)
//                .setAction("Action", null).show();
        Intent intent = new Intent(this,CustomActivity.class);
        startActivity(intent);
    }

再后,在代码中set事件进去。

binding.setVariable(BR.handler,this);

最后,看下我们的布局。

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <data>
        <variable
            name="user"
            type="beans.User"/>
        <variable
            name="handler"
            type="events.ClickHandler"/>
    </data>
    <RelativeLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/content_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="gl.com.databindingdemo.MainActivity"
        tools:showIn="@layout/activity_main">

        <TextView
            android:layout_marginTop="50dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.username}"
            android:onClick="@{handler::onClickTest}"
            />
    </RelativeLayout>
</layout>

注意@{handler::onClickTest} ,和下面的差别,要注意啦。

哈哈,简单吧。

3.2 监听事件

和上面的类型,不过,我们这里的接口中不在是View,而是其他的东西,比如实体类。我们要在点击的时候保存,这时候怎么办呢?

public interface SaveHandler {

    public void saveUser(User user);
}

对应布局文件中的代码变成这样子。

android:onClick="@{()->handler.saveUser(user)}"

各位老司机一定知道,这是啥子了吧。当事件发生的时候,会执行对应的lambda表达式。

关于这两个的区别,这里就不说了。各位大大看这里两者的区别,需烦请

4. 详细说说Layout

通过上面,我们已经了解了DataBinding。但是,还远远不够,接着继续。

  • Imports
  • Variables
  • Includes
  • Expression Language
4.1 imports

假如我们想用View.GONE 咋办,如何吧View到进来呢。在 data下面

<import type="android.view.View"/>

其他额外的类也是这样的。

4.2 Variables
<variable
    name="user"
    type="beans.User"/>
  • name 是在xml文件中用的变量名
  • type是类型
  • 这里也可用一些其他的类型。如List、Map等等

4.3 includes

这里指我们的include标签。在使用include标签的时候要注意。

<include layout="@layout/content_main"
            bind:user="@{user}"
            bind:handler="@{handler}"
            />

使用bind的方式,把当前的data绑定到include对应的文件。千万要注意了,

4.4 Expression Language

支持如下

android Gson超大数据 android databing_xml

暂时部支持:super、this、new操作符。

下面的这一点比较好玩。

android:text="@{user.displayName ?? user.lastName}"
//等于
android:text="@{user.displayName != null ? user.displayName : user.lastName}"

这个是不是很有意思。

集合类的支持

  • android:text="@{list[index]}"
  • android:text="@{map['firstName']}" 注意 用单引号

资源Resource支持

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

甚至还可以用格式化字符串那套

android:text="@{@string/nameFormat(firstName, lastName)}"

<string name="nameFormat">%s, %s</string>

这 厉害了。

5. 数据的变化如何反应到UI上

要想让数据的变化立马相应在UI上,我们有如下办法。

  • Observable Objects
  • ObservableFields
  • Observable Collections
5.1 Observable Objects

我们的Bean需要继承BaseObservable,并且在set方法中(改变属性)调用notifyPropertyChanged或者notifyChange即可。

5.2 ObservableFields
public final ObservableField<String> userName =
       new ObservableField<>();

我们只需要调用set方法改变属性即可。set方法代码如下

public void set(T value) {
        if (value != mValue) {
            mValue = value;
            notifyChange();
        }
    }
5.3 Observable Collections

同理

我们来看下对应包下有那些,如图

android Gson超大数据 android databing_xml_02

6. 总结

到这里,我们的基础用法学完了,还有一些非常高级的用法还没看到,大家快去尝试下吧,


参考资料
* Android developer
* 大帅的文章