DataBinding详细的使用方法及工作中常遇到的问题(一)

前言

用DataBinding差不多现经手了三个项目,也用它开发了一年左右,对它的特性以及使用方面有了一些自己的理解,这里面可以和大家一起分享一下,详解DataBinding文档中的知识点,以及工作中可能遇到的一些问题,我每讲一部分都是写一个相应的demo以供参考.

DataBinding是什么?

官网文档地址:https://developer.android.com/topic/libraries/data-binding/index.html
翻译文档:自己谷歌搜索,网上已经有,这里就不再翻译
官方文档的原话是:Data Binding Library to write declarative layouts and minimize the glue code necessary to bind your application logic and layouts,The Data Binding Library offers both flexibility and broad compatibility — it's a support library,大致的意思就是DataBinding是一个通过胶水代码写声明布局文件并减少绑定应用程序逻辑的一个具有兼容和灵活性的一个支持库.看了之后还是一脸懵逼,不要紧,学知识嘛,慢慢来.

如何集成

集成很简单,在你app module的Gradle下面添加的代码:

android {
    ....
    dataBinding {
        enabled = true
    }
}

提醒:现在建议大家的AS更新到最新,目前最新稳定版式2.3.3.另外,你们公司如果接受了DataBinding这个还算有点新的东西,那么我建议大家使用JDK1.8,具体的详细介绍,请看官网上面的介绍,https://developer.android.com/guide/platform/j8-jack.html.

AS2.1以上才支持jack,如果你得AS版本比较低的话,可以使用兼容库Retrolambda.目前的稳定版而言,暂时不能使用instant run.
集成如下:

android {
    defaultConfig {
        ....
        jackOptions {
            enabled true
        }
    }
    ....
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

note:如果你用的AS3.0的话,就可以不通过jack进行编译,而且可以使用instant run,还加快的编译速度.具体的介绍:
http://developers.googleblog.cn/2017/05/android-studio-30-canary-1.html

如何使用

在工作中,我们经常遇到请求到一个对象,然后对象的信息需要在xml中展示的情况,用它怎么做到吗?比普通的做法有什么优势?

  • 假如我们请求到的是一个学生的实体类,那么我们先创建一个学生类:
public class Student {
    private String name;
    private int age;
    private String headerImg;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHeaderImg() {
        return headerImg;
    }

    public void setHeaderImg(String headerImg) {
        this.headerImg = headerImg;
    }
}
  • 这个学生类包括姓名,年龄和头像的url,现在我们模拟一下网络请求:
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo1);
        initData();
    }

    private void initData() {
        //模拟网络请求部分,假如请求到了一个学生实体
        Student student = new Student();
        student.setAge(25);
        student.setName("李宁");
        student.setHeaderImg("http://i2.muimg.com/567571/b528af67d68f7597.png");
    }
  • 下面正常的做法就是拿到xml里面的空间,然后一个一个赋值上去,是不是感觉这样做不仅要findViewById,还要拿到各种控件进行一系列的赋值挺麻烦的,这时候DataBinding的作用就展示出来了,数据绑定,就是要把数据直接绑定到xml上面.下面看我华丽的操作:
XMl中:
<?xml version="1.0" encoding="utf-8"?>
<layout>

<data>

    <variable
        name="student"
        type="com.DataBinding.lsh.databindingdemo.Student" />
</data>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical"
                  tools:context="com.DataBinding.lsh.databindingdemo.Demo1.Demo1Activity">


    </LinearLayout>
</layout>

跟布局的标签换了,换成了layout,其次多了data标签,下面有个一个varible标签,它的作用就是用来声明xml中绑定的变量,这里面的Type一定要写引用的全路径,不过好在现在都可以智能提示,打上一个Student,选择正确的一个,下面我们就要在xml的控件中绑定我们声明变量的字段,你可能会说,咦?student只是声明了,不是还没有给进行赋值吗?现在绑定上去不会报错吗?这个不用担心,它有一系列的默认值.一阵乱敲之后:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="student"
            type="com.DataBinding.lsh.databindingdemo.Student" />
    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  xmlns:fresco="http://schemas.android.com/apk/res-auto"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical"
                  tools:context="com.DataBinding.lsh.databindingdemo.Demo1.Demo1Activity">

        <com.facebook.drawee.view.SimpleDraweeView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_gravity="center"
            fresco:actualImageScaleType="fitXY"
            fresco:placeholderImage="@mipmap/ic_launcher"
            fresco:placeholderImageScaleType="centerCrop"
            fresco:roundAsCircle="true" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="李宁"
            android:textSize="24sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="25"
            android:textSize="24sp" />


    </LinearLayout>
</layout>

我这里面用的加载图片的工具是fresco,它很强大,尤其在内存方面,而且还有一集成了一些常用的功能,比如圆形头像,圆角头像,gif播放,等常用的一些功能.

接下来开始绑定:


先绑定TextView的属性,写法如上述图片,控件中自带的这些属性一般可以直接绑定,如果想绑定一些没有的属性,就需要自己去指定,下面绑定图片地址展示图片的时候会用到.我们xml中除了图片,文本就绑定好了,那么activity要怎么操作呢?

在Activity中:
  • DataBinding通过DataBindingUtil来进行绑定视图,常用的有两个方法,一个是setContentView方法,一个是bind方法,前者一般用着Activity加载视图,后者就是Fragment等.
  • 一个xml对应一个Binding的java文件,这个文件是自动生成的,如果提示不出来这个类,重启As,如果还是不行,把项目中的build文件夹删除了,重新编译,满满的都是经验啊.这个类在build下面是可以找到的,路径如下图:
  • 最后我们对xml中的变量进行赋值

异常
我们愉快的编译运行,忽然闪退了,看异常:


点进去:

mboundView2就是我们设置年龄文本,后面的studentAge就是我们设置的年龄,这地方怎么会报错呢?
想一想,原来是我们student的age是int类型的,但是text属性不能直接设置int类型,那怎么办?
在string.xml中

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{@string/intToString(student.age)}"
            android:textSize="24sp" />

在activity_demo1.xml中:

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{@string/intToString(student.age)}"
            android:textSize="24sp" />

其他的类型的转化就可以参照这个去改.

绑定图片

public class ViewBindAdapter {
    @BindingAdapter({"bind:url"})
    public static void setImgUrl(SimpleDraweeView imageView, String uri) {
        if (!TextUtils.isEmpty(uri)) {
            imageView.setImageURI(Uri.parse(uri));
        }
    }
}

xml中:

        <com.facebook.drawee.view.SimpleDraweeView
            app:url="@{student.headerImg}"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_gravity="center"
            fresco:actualImageScaleType="fitXY"
            fresco:placeholderImage="@mipmap/zhanwei"
            fresco:placeholderImageScaleType="centerCrop"
            fresco:roundAsCircle="true" />

我们新建一个类,专门存放绑定的自定义属性,@BindingAdapter({"bind:url"})这句主要是声明xml中写的自定义的属性,可以连续写多个,比如这种:

  @BindingAdapter(value = {"uri", "placeholderImageRes", "request_width","request_height"}, requireAll = false)
    public static void loadImage(final ImageView imageView, String uri,
                                 @DrawableRes int placeholderImageRes,
                                 int width, int height){
                                 }

requireAll = false的意思是不用写全所有参数,方法的第一个参数是控件的本身,就是这么简单,这样就可以绑定成功了.

note:注意app:url="@{student.headerImg}"这个没有智能提示,代码颜色也没有改变,都是正常的,只要写对就行.

最新来一张图:


到这里,这些基本的操作就完成了,你已经对databinding有了一个大体的认识,接下来的几篇,将会更加深入的介绍它的使用方法和底层的原理.
demo地址:https://github.com/adonis-lsh/DataBindingDemo

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

推荐阅读更多精彩内容