上一篇文章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 盡請期待!