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

来源:互联网 发布:修改路由器lan口mac 编辑:程序博客网 时间:2024/06/01 07:34

前言

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)

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

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

1 0