Android Jetpack系列——细说DataBinding

2019-05-17 12:13:16 浏览数 (1)

DataBinding 背景

DataBinding 是谷歌最早在2015年官方发布的一个框架,顾名思义即为数据绑定。而推出 DataBinding 的目的就是为了减少繁琐的代码,使代码更加的简洁、可读性更强。随着这几年的发展, DataBinding 日渐成熟,应用愈发的广泛。

DataBinding 的好处

当然,我们就不在需要使用 FindViewById 了,其实之前,我们就可以看到很多框架都尝试不在使用 FindViewById 比如 Butterknife 、 XUtil 、 Dragger 等等,但是随着谷歌官方推出了 DataBinding , Kotlin 很多框架都不在使用,甚至很少更新,甚至不更新了。

使用 DataBinding 会让我们的布局文件不简简单单的只有一个布局文件的作用,还包含和很多的逻辑。可以大量减少 Activity 内的代码。

同时 DataBinding 还会让我们的代码更有层级,结构更加的清晰完善,数据能够单向或者双向绑定到布局文件当中。这样有助于防止内存泄露,而且能够自动进行空检测以避免空指针异常。

DataBinding 的集成

DataBinding是一个支持库,它可以运行在Android 4.0(API级别14)或更高版本的设备上。

启用 DataBinding 的方法,首先在对应的 Model 的 build.gradle 文件当中加入以下代码,同步之后就能引入对于 DataBinding 的支持。

代码语言:javascript复制
android {
 
     //引入对 DataBinding 的支持
    dataBinding {
        enabled = true
    }
}

以前版本的数据绑定编译器,在编译代码的同步当中生成绑定类。 如果我们的代码无法编译,我们将会可能会收到多个错误报告未找到绑定类。 新的数据绑定编译器通过在托管编译器构建应用程序之前生成绑定类来防止这些错误。

使用新的数据绑定的编译器,我们只需要在gradle.properties文件当中,添加上

代码语言:javascript复制
android.databinding.enableV2=true

或者,在我们的gradle文件当中,添加上如下的参数

代码语言:javascript复制
-Pandroid.databinding.enableV2=true

接下来,在布局文件当中,选中根布局的ViewGroup,然后按住 「Alt 回车键」 如图

点击 「Convert to data binding layout」 即可生成就可以生成 DataBinding 需要的布局规则 我们可以看到,代码如下:

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>

    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

至此,关于 DataBingding 的集成工作已经完成,接下来,我们要开始讲讲 DataBinding 的使用。

DataBinding 的简单使用

DataBinding 有很多应用场景和方法,为了介绍的详细一些,我会专门介绍一下 DataBinding 的使用,接下来我们只介绍一下 DataBinding 的简单的使用。

对比之前的布局文件,我们发现多出了一个「layout」标签将原来的布局包裹起来,同时还多了一个「data」标签,这个标签是用来声明要用到的变量以及变量的类似使用。

使用 DataBinding 是实现 MVVM 框架必不可少的结构,而 「data」标签就是构建了 View 和 Model 之间的连接通道。这样就可以把数据层(Model)与 UI层(View)绑定在一起了。

接下来我们要声明一个Model

代码语言:javascript复制
package com.yang.databindingdemo.model


data class Student(val Name: String, val Age: String)

接下来,在「data」标签当中声明要使用到的变量、类的全路径。

如下

代码语言:javascript复制
  <data>
        <variable name="studentInfo"
                  type="com.yang.databindingdemo.model.Student"/>
    </data>

需要注意的是

如果我们使用的Student类型会在很多地方用到,我们也可以采用「import」的方式引进来,这样我们就不用每次都指明整个包名的路径了。

如下

代码语言:javascript复制
   <data>
        <import type="com.yang.databindingdemo.model.Student"/>
        <variable name="studentInfo"
                  type="Student"/>
    </data>

如果我们「import」相同,我们还可以采用增加「alias」字段来指定别名。

如下

代码语言:javascript复制
    <data>
        <import type="com.yang.databindingdemo.model.Student"/>
        <import type="com.yang.databindingdemo.model2.Student"
                alias="Student2"/>
        <variable name="studentInfo"
                  type="Student"/>
        <variable name="student2Info"
                  type="Student2"/>
    </data>

介绍完以上内容之后,我们开始正式使用DataBinding。

声明了一个 Student 的类似数据变量 「studentInfo」,接下来我们就需要把 Student 当中的两个变量和布局文件当中的 TextView

控件关联上,而我们的关联的方式就是我们的数据变量 「studentInfo」。

通过设置「studentInfo」变量值,同时使 TextView 显示我们要设置的文本信息,完整代码如下

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <import type="com.yang.databindingdemo.model.Student"/>
        <variable name="studentInfo"
                  type="Student"/>
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                android:id="@ id/tv_studenname"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{studentInfo.name}"
                android:textSize="20sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.377"/>

        <TextView
                android:id="@ id/tv_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{studentInfo.age}"
                android:textSize="20sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.276"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

通过代码我们可以看大搜,通过 「@{studentInfo.name}」可以 让对应的 TextView 控件引入对应的变量。因为 「@{studentInfo.name}」没有任何的值,在布局文件当中不便于观察,我们可以添加 「default」 属性 如下

代码语言:javascript复制
  android:text="@{studentInfo.name,default = Yang}"
  
  android:text="@{studentInfo.age,default = 18}"

这样我们就可以在布局文件当中看到:

这样我们就方便在布局文件当中查看,以便添加 TextView 控件的相关属性。

写好之后,我们同步一下,就可以发现 多了一个「ActivityMainBinding」的类,位置如图

默认情况下,这个类的名称基于布局文件的名称创建的,将其转换为Pascal大小写并向其添加Binding后缀。上面的布局文件名是activity_main.xml,因此相应的生成类是ActivityMainBinding。

接下来我们就需要在Activity当中为「userInfo」赋值了。如下

代码语言:javascript复制
package com.yang.databindingdemo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.yang.databindingdemo.databinding.ActivityMainBinding
import com.yang.databindingdemo.model.Student

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main
        )
        binding.studentInfo = Student("杨大爷", "20")
    }


}

效果如图:

最后

至此,介绍了DataBinding,并且介绍了DataBinding的简单的使用,是不是让你对DataBinding又了一个全新的了解和认识呢?接下来,我再详细的介绍一下如何使用DataBinding,敬请期待!

0 人点赞