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 下載
若有任何問題 關注 「朝陽楊少爺」 公衆號給我留言,我會及時回覆。

掃一掃,即刻加入到專屬限免的星球當中,這裏有不少有意思的人,好玩兒的事兒等你來耍!

相關文章
相關標籤/搜索