上一篇文章android
咱们介绍了DataBinding以及DataBinding的简单的使用。能够看到,咱们上一篇文章只是简单介绍了一下DataBinding,并无详细介绍如何动态的加载数据。也就是说,这篇文章,咱们将介绍,如何使用DataBinding让视图跟随这数据进行刷新变化。github
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面能够做为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。观察者模式有不少实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。bash
以上就是观察者模式的一个简单概念,而谷歌在这里开发的思想也是采用这种观察者模式的思想。数据结构
DataBinding的库,容许咱们使用对象,字段,或者集合均可以进行观察。当其中的一个可观察者数据对象绑定到了视图当中,而且数据对象的属性发生更改变化的时候,视图将会自动更新。app
ObservableField默认已经帮咱们作了不少工做,好比实现了一系列的Observable接口的字段类型。ide
这其中包括布局
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
复制代码
在实际代码当中实际方式表现为。post
经过代码实现的效果:ui
咱们的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为例:
咱们在 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<String, Object>"/>
</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<String, Object>"/>
复制代码
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 尽请期待!