为了账号安全,请及时绑定邮箱和手机立即绑定

DataBinding 使用进阶——数据绑定

这是第「24篇」原创分享

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

背景

上一篇文章Android Jetpack系列——细说DataBinding,我们介绍了DataBinding以及DataBinding的简单的使用。可以看到,我们上一篇文章只是简单介绍了一下DataBinding,并没有详细介绍如何动态的加载数据。也就是说,这篇文章,我们将介绍,如何使用DataBinding让视图跟随这数据进行刷新变化。

观察者模式

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

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

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

ObservableField

ObservableField默认已经帮我们做了很多工作,比如实现了一系列的Observable接口的字段类型。

这其中包括

ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable

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

通过代码实现的效果:

我们的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 下载
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
35
获赞与收藏
116

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消