Android DataBinding(数据绑定)详解(一)

版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/JavaAndroid730/article/details/71599808

前言

Android DataBinding,在如今来看已经不算陌生,在网上也多多少少有好的文章介绍它,很多朋友早就耳闻它的大名,通过学习并运用在自己的项目中。那今天为什么我还要再写一个DataBinding的教程呢?相信很多朋友和我一样,在学习中发现,网上大部分的教程都存在不同的缺陷,要么内容不完整,要么就是没有系统化的讲解方向,都是一股脑的一篇文章全部抛出。所以针对这些问题,我写下这个教程,帮助那些还没有接触DataBinding的朋友入门。

注:如果你觉得写得不好或者不详细,请直接批评指出,评论或私信尽情轰炸我吧。

目录

以下是我总结出的学习顺序,可以方便朋友们学习和复习。老规矩,有错误的地方请尽情的批评指出。

初级篇

  • Android DataBinding(数据绑定)详解(一)

    • 什么是DataBinding
    • DataBinding的优点及不足
    • DataBinding的基础用法
  • Android DataBinding(数据绑定)详解(二)

    • DataBinding原理
  • Android DataBinding(数据绑定)详解(三)

    • 常用的表达式
    • 人性化的null检查机制
    • include导入其他布局
  • Android DataBinding(数据绑定)详解(四)

    • observable
    • 高级绑定

高级篇

  • Android DataBinding(数据绑定)详解(五)

    • 列表绑定
    • 列表绑定之番外篇
  • Android DataBinding(数据绑定)详解(六)

    • 自定义属性带来的便捷
    • 神奇的双向绑定
  • Android DataBinding(数据绑定)详解(七)

    • 表达式链
    • 逼格高的Lambda表达式
  • Android DataBinding(数据绑定)详解(八)

    • DataBinding的动画
    • 方便的UI测试
  • Android DataBinding(数据绑定)详解(九)

    • 温故而知新
    • 不舍的完结,DataBinding的使用建议

1、什么是DataBinding

DataBinding是Google在2015年I/O大会介绍的一个帮助开发者处理视图与数据交互的框架(官方原生支持 MVVM),字面理解即为数据绑定。它给我们带来了很大的方便,其中最直接的便是省去findViewById,说到这里,其实网上也有很多注解框架(例如:ButterKnife、AndroidAnnotations),但是与DataBinding相比还是不好用。在Google官网文档还说,DataBinding还能提高解析XML的速度,其实DataBinding的好用,不仅仅体现在可以省去使用很多啰嗦findViewById,还有很多。往下看你就会明白的。

2、DataBinding的优点及不足

优点:

  • 节省代码,省去了findViewById()
  • 兼容性高,兼容到Android2.1(API 7)
  • 支持绝大部分的 Java 写法
  • 支持lambda表达式
  • 不使用反射,保证了性能
  • 数据直接绑定在XML中
  • 最新的支持双向绑定
  • 支持在任意线程更新数据(列表类型除外)
  • 避免了因数据导致的空指针(null)

缺点:

  • IDE支持还不那么完善(xml中代码自动补全大部分需要手写)
  • 报错信息不那么直接
  • 没有重构的支持
  • 需要遵循DataBinding的格式

3、DataBinding的基本用法

好了,说了一大堆废话,终于可以开始我们正式的学习和运用了。接来下所有讲解,将在Demo中演示,在最后的文章会提供GitHub地址,请大家安心学习。

第一步,环境搭建:
打开项目,在build.gradle(Module:app)中添加如下代码

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

完整代码如下:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "app.fengjun.com.databinding_demo"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
//    DataBinding环境搭建
    dataBinding {
        enabled = true
    }
}

第二步,基础使用:
省去findViewById(赶紧替换ButterKnife吧!)
新建Explain1Activity类并创建对应的activity_explain1.xml布局,在布局最外层嵌套layout,代码如下

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv_age"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btn_clcik"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button"
            android:textAllCaps="false" />
    </LinearLayout>
</layout>

布局中有带有id的2个TextView和1个Button,我们将对他们进行操作。注意:当布局外嵌套layout后,系统会自动帮我们生成对应的Binding类,生成类名规则为:布局名称大写+Binding,省去_符号。如果没有生成,需要Rebuild Project。

然后在Explain1Activity中,我们编写如下代码,具体代码如下:

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

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

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
public class Explain1Activity extends AppCompatActivity {

    private ActivityExplain1Binding binding;
    private Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_explain1);
        student = new Student("FynnJason", "100");
        binding.tvName.setText(student.getName());
        binding.tvAge.setText(student.getAge());
        binding.btnClcik.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(Explain1Activity.this, "被点击了", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

可以看到,我们用Binding生成的对象去替换原来的setContentView,参数第一是上下文(this),第二个是布局。我们通过这个对象就可以拿到视图中的控件,然后对他们进行操作。那么,省去findViewById就完成了!是不是极其简单。运行效果如图:
运行效果

虽然效果实现了,但这并没有体现数据绑定的特性啊,不用急,我们修改布局,修改如下:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="student"
            type="app.fengjun.com.databinding_demo.explain1.Student" />

        <variable
            name="presenter"
            type="app.fengjun.com.databinding_demo.explain1.Explain1Activity.Presenter" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{student.age}" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{presenter.onClickButton}"
            android:text="Button"
            android:textAllCaps="false" />
    </LinearLayout>
</layout>
public class Explain1Activity extends AppCompatActivity {

    private ActivityExplain1Binding binding;
    private Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_explain1);
        student = new Student("FynnJason", "100");
        binding.setStudent(student);
        binding.setPresenter(new Presenter());
    }

    public class Presenter {
        public void onClickButton(View view) {
            Toast.makeText(Explain1Activity.this, "被点击了", Toast.LENGTH_SHORT).show();
        }
    }

}

我们在布局文件中,添加了data便签,在data便签里面又使用了variable标签,在variable便签中,name我们可以自定义,type就是我们的数据源和方法源,这里对应了Student数据和Present类的方法,这样,我们就省去了设置id,直接对属性进行数据绑定和监听操作,具体是使用@{}语句。

需要注意的是,监听方法需要严格遵循Android规范,比如这里点击事件方法中要传入View(当然方法名称是可以随意的),如果不传会崩的哦!你可能要问了,那如果我真的忘记传了呢,不急,我们还可以用lambda写法,它就不用严格遵循Android规范,但这里不做介绍,毕竟一口吃不成胖子嘛。接下来我们在Activity中要用Binding对象将数据源set进去,相信大家看代码就已经清楚怎么做了(你说没看懂,那我也很绝望啊!QAQ)

然后我们再运行,效果是刚刚一样的,所以这里就不贴图了。大家是不是觉得很神奇!

好了,本次的教程就到底结束了。大家有什么疑问可以在下面评论留言,欢迎批评指出。

阅读更多
换一批

没有更多推荐了,返回首页