Android使用DataBinding入门

2015年的GoogleI/O大会上,Google推出了自己官方的数据绑定框架Data Binding Library,虽然网络上有很多第三方的数据绑定框架,但是,第三方的框架都是别的公司或者团队在维护,有些公司或者团队看到自己的东西没有很好的收益或者其他原因,一下子就不在维护了,这对我们来说就是一个大麻烦,所以,使用官方的框架是我们第一个选择。

在没有出来这个以前,我们获取控件的句柄一般是通过findViewById或者使用注解,使用注解虽然是不需要我们写很多的findViewById,但是大量使用注解会拖慢我们APP的速度。但是使用Data Binding就不会,根据官方文档的解析,使用Data Binding还会提高XML的解析速度。Data Binding的推出,解决了Android UI编程的一个痛点,是Google官方对MVVM在Android上的一个实现,我们可以在不改变原有框架的基础上,使用这些新特性。使用Data Binding可以让我们开发中减少很多与UI相关的代码,可以直接将数据绑定到XML上,可以实现自动刷新。

下面开始使用这个官方的大杀器

1、开发环境

将Android studio更新到最新版本,现在Google也在我大天朝上线了开发者网站,我们不在需要跨过长城了,下面提供一下Google在天朝的开发者网站地址:https://developer.android.google.cn/index.html

更新完Android studio之后,将Gradle也更新到新的版本,最少不低于1.5.0版本,我用的是最新的2.2.3版本:

 classpath 'com.android.tools.build:gradle:2.2.3'

然后在当前model的android{}闭包中添加对Data Binding的支持:

android {
    ...
    dataBinding {
        enabled true
    }
}

这样准备好了环境,下面开始一个简单的例子

2、Data Binding简单例子

在上面的环境准备好了之后,我们可以开始编写代码:

首先,我们需要一个普通的JavaBean,一个简单的Student类:

public class Student {
    private String name;
    private String addr;

    public Student() {
    }

    public Student(String name, String addr) {
        this.name = name;
        this.addr = addr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddr() {
        return this.addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

这是一个简单的JavaBean,提供相应的get和set方法。

接着是布局文件的编码:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="com.databindingdemo.Student"/>
        <variable
            name="stu"
            type="Student"/>
    </data>

    <LinearLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.databindingdemo.MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.name}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.addr}"/>
    </LinearLayout>
</layout>

需要注意的是,根布局不再是以前ViewGroup,而是一个Layout,里面的命名空间不能重复,比如有android的约束就不能在ViewGroup的根节点中重复使用,否则编译不过去的。

完成布局代码之后,就是Activity的编码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding a = DataBindingUtil.setContentView(this, R.layout.activity_main);
        a.setStu(new Student("Devin", "广州"));
    }
}

这样就可以实现在我们布局中显示数据,最后的结果是:

这样我们就可以很简单地实现了一个Data Binding的例子。这样在Activity中我们就不需要写很多的代码,activity里面也变得非常简洁明了。

3、Data Binding入门

上面我们简单实现了Data Binding,下面我们详细地了解一下。

首先从布局文件入手,先看一下布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <import type="com.databindingdemo.Student"/>
        <variable
            name="stu"
            type="Student"/>
    </data>
    <LinearLayout
       ...
    </LinearLayout>
</layout>

布局文件中,根节点不再是ViewGroup,而是layout,layout下面有两个节点,分别是<data>和<LinearLayout>,LinearLayout是一个ViewGroup,ViewGroup里面写我们具体的布局代码,data里面就是我们绑定的数据,下面解析一下data这个节点。

    <data>
        <import type="com.databindingdemo.Student"/>
        <variable
            name="stu"
            type="Student"/>
    </data>

data节点里面有两个节点,分别是import和variable,import就是引入JavaBean对象,type的值就是全限定类名。我们可以引入多个类,当引入的类同名的时候,我们还可以在import中添加一个类的别名,例如:

<import type="com.example.home.data.User" />
<import type="com.examle.detail.data.User" alias="DetailUser" />
<variable name="user" type="DetailUser" />

这里引入的类名字都是User,我们可以用alias这个属性起一个别名,用于区分不同的类,这是import标签,下面了解一下variable标签。

其中variable就是我们用来定义变量的,在上面的例子中我们就定义了一个stu变量,类型就是一个JavaBean,我们还可以定义List、Map、String等的变量,例如:

    <variable
        name="list"
        type="ArrayList&lt;String>" />
    <variable
        name="map"
        type="HashMap&lt;String, String>" />

等等,然后我们就可以在布局文件中使用这些定义的变量,这个就是variable标签的基本作用。

这里就是布局文件的基本解析,下面了解一下Activity里面的代码:

  @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,
            R.layout.activity_main);
    mainBinding.setStu(new Student("Devin", "广州"));
}    

这里的代码非常简单,就两句代码。下面我们了解一下

DataBindingUtil是layout创建数据绑定类,当我们使用这个类并调用setContentView()方法的时候,会创建一个ActivityMainBinding对象,这个ActivityMainBinding是Data Binding自动生成的,根据布局文件命名,比如我们这里的布局文件名是:activity_main,然后生成的就是ActivityMainBinding,这个类的基类是ViewDataBinding,然后调用set方法将数据注入进去,最后就可以实现数据的展示。

ActivityMainBinding这个类是自动生成,生成的规则是:

布局文件名首字母大写,去掉下划线,下划线后面首字母大写,加上Binding

除了可以这样直接生成之外,Google还给我提供了自定义Binding类名的方法,就是在data中加一个class字段就可以了。

4、Data Binding其他使用

绑定事件

我们通常给Button设置点击事件都是通过注解绑定或者setOnClickListener,Data Binding也给我提供了可以绑定事件的方法,下面我们具体实现一下。

首先是布局文件的代码:

<data>

    <import type="com.databindingdemo.Student"/>

    <import type="com.databindingdemo.OnClickListener"/>

    <variable
        name="stu"
        type="Student"/>

    <variable
        name="click"
        type="OnClickListener"/>
</data>

需要定义一个OnClickListener类,这里面是我们的点击事件:

public class OnClickListener {

    public void onClick(View view) {
        Toast.makeText(view.getContext(), "绑定了点击事件", Toast.LENGTH_LONG).show();

    }
}

然后在布局文件中使用:

     <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{click.onClick}"
        android:text="绑定点击事件"/>

最后在activity中做一个设置:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,
            R.layout.activity_main);
    mainBinding.setStu(new Student("Devin", "广州"));
    mainBinding.setClick(new OnClickListener());
}

这样就可以实现点击事件。

表达式

Data Binding也支持使用表达式,下面是Data Binding的常用表达式跟JAVA的表达式差不多

  • 数学计算 + / * %
  • 字符串连接 +
  • 逻辑 && ||
  • 二进制 & | ^
  • 一元 + ! ~
  • 位移 >> >>> <<
  • 比较 == > < >= <=
  • instanceof
  • 组 ()
  • 字面量 字符,字符串,数字, null
  • 类型转换
  • 函数调用
  • 字段存取
  • 数组存取 []
  • 三元运算符 ?:

有一个特殊的就是null合并,例如:

android:text='@{str==null ?? "not null"}'

解析一下:str是否是null,是null的话text的值就是str,否则就是not null里面的值,类似与三目运算符。

数据刷新

Data Binding给我们提供了内容观察者去刷新数据的改变,这个跟我们在RecyclerView中设置Adapter通过调用notifyDatasetChanged()方法通知UI刷新数据一样。Google官方给我们提供了非常简单的一种方式去实现,下面我们了解一下具体的步骤:

  1. JavaBean继承BaseObservable这个类

  2. 在Getter方法上面添加@Bindable注解

  3. 在Setter方法中调用notifyPropertyChanged(BR.name);

这样就可以完成了,是不是很简单。我们会发现,在notifyPropertyChanged()方法中有一个参数,BR,那么BR是什么呢?BR跟R差不多,保存我们变量的引用地址。

上面就是Data Binding的基本解析,当然还有其它很多的高级用法,欢迎大家留言交流!!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容