DataBinding 使用进阶——数据绑定

看了谷歌官方文章确实写的太简略了,甚至看完以后有不少地方还不知道怎么回事儿或者怎么用,那么接下来我将经过几篇文章全面介绍一下 DataBinding 以及 DataBinding 的使用。
GitHub传送门 欢迎Star 下载
若有任何问题 关注 “朝阳杨少爷” 公众号给我留言,我会及时回复。

背景

上一篇文章android

juejin.im/post/5cdbff…git

咱们介绍了DataBinding以及DataBinding的简单的使用。能够看到,咱们上一篇文章只是简单介绍了一下DataBinding,并无详细介绍如何动态的加载数据。也就是说,这篇文章,咱们将介绍,如何使用DataBinding让视图跟随这数据进行刷新变化。github

观察者模式

观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面能够做为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。观察者模式有不少实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。bash

以上就是观察者模式的一个简单概念,而谷歌在这里开发的思想也是采用这种观察者模式的思想。数据结构

DataBinding的库,容许咱们使用对象,字段,或者集合均可以进行观察。当其中的一个可观察者数据对象绑定到了视图当中,而且数据对象的属性发生更改变化的时候,视图将会自动更新。app

ObservableField

ObservableField默认已经帮咱们作了不少工做,好比实现了一系列的Observable接口的字段类型。ide

这其中包括布局

ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
复制代码

在实际代码当中实际方式表现为。post

经过代码实现的效果:ui

ObservableField.gif

咱们的Model层为:

class Student {
    val name = ObservableField<String>()
    val age = ObservableInt()
}
复制代码

代码当中实现为:

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
        )
        val studentInfo = Student()
        studentInfo.name.set("我叫朝阳杨大爷")
        studentInfo.age.set(20)
        binding.studentInfo = studentInfo

        binding.tvStudenname.setOnClickListener {
            studentInfo.name.set("我仍是叫叫朝阳杨大爷")
        }
        binding.tvAge.setOnClickListener {
            studentInfo.age.set(18)
        }

    }


}

复制代码

布局文件当中:

<?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,default = Yang}"
                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="@{String.valueOf(studentInfo.age),default = 18}"
                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.474"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
复制代码

ObservableArrayMap/ObservableArrayLis/ObjservableMap

实现以上效果,咱们还可使用集合类型,这里为咱们提供了三种数据结构类型。

ObservableArrayMap
ObservableArrayLis
ObjservableMap
复制代码

这里咱们以ObservableArrayMap为例:
咱们在 Activity 当中代码为

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main
        )
        val map = ObservableArrayMap<String, Any>()
        map["name"] = "我叫杨大爷"
        map["age"] = 20
        binding.studentInfo = map
    }
}

复制代码

而后布局文件当中为:

<?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="androidx.databinding.ObservableArrayMap"/>
        <variable name="studentInfo" type="ObservableArrayMap&lt;String, Object&gt;"/>
    </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`],default = Yang}"
                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="@{String.valueOf(studentInfo[`age`]),default = 18}"
                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.474"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
复制代码

几点注意事项

1.androidx的引用

注意,咱们这里引用的 ObservableArrayMap 为 androidx 包下的,因此咱们在布局文件当中引用的 ObservableArrayMap 为

androidx.databinding.ObservableArrayMap" 复制代码

2.编译以后出现:与元素类型 "null" 相关联的 "type" 属性值不能包含 '<' 字符。的问题

在xml当中不能使用<应该用它的转义字符好比,<
因此,咱们在代码当中须要修改成:

<variable name="studentInfo" type="ObservableArrayMap&lt;String, Object&gt;"/>
复制代码

3.编译以后出现:/ data binding error msg:Identifiers must have user defined types from the XML file. name is missing it问题

可能是由于,在引用的时候的问题 ObservableArrayMap 的key的问题, 这里,咱们在引用的时候,注意

android:text="@{studentInfo[`name`],default = Yang}"
复制代码

key上要有个英文的引号才能够。

4.当使用int给xml属性赋值时,若是该属性接受资源id,那么这个int会认为是资源的id。若是android:text=@{1}, 这样子text不会显示1,反而会报错,由于找不到id为1的资源

5.切记,达式里面不能有中文,不然会报错

6.在写表达式的时候,不能换行

最后

经过这篇文章,咱们真正的了解如何使用 DataBinding 而且了解了数据绑定,对于数据绑定的使用。

使用 DataBinding 确实代码会显得更加优雅一些,不少 UI 逻辑在 xml 文件当中就能实现了。

可是,咱们必定要注意的是,在使用 DataBinding 的时候,应当注意要保持 xml 的简洁性, 不要再 xml 当中加入 过多的业务逻辑。

接下来咱们将继续深刻介绍 DataBinding 尽请期待!

GitHub传送门 欢迎Star 下载
若有任何问题 关注 “朝阳杨少爷” 公众号给我留言,我会及时回复。

扫一扫,即刻加入到专属限免的星球当中,这里有不少有意思的人,好玩儿的事儿等你来耍!

相关文章
相关标签/搜索