iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0

Databinding 與 Observable

目前爲止我們已經實現了透過 Databinding 完成數據綁定的方式,但是每次當數據改變時(例如:api 的 response 回來了),都要重新向 ViewDataBinding 傳遞新的數據並刷新 UI,有沒有辦法能做到數據更新後 UI 也能 自動 刷新呢,答案就是透過 觀察者模式,也就是本篇的重點 Observable ,這是 Databinding 支持的庫,而且使用起來也非常方便。

這裡我來做一個計時器能定時對 ViewModel 發送數據,並讓 UI 能夠同步更新

layout 很簡單,一個 TextView 來顯示 ViewModel 裡的 num

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{String.valueOf(viewModel.num)}" />

每隔兩秒都向 ViewModel 發送數據,發送完後的 num 都會再加一,方便我知道下次更新 ViewModel 時 UI 到底有沒有更新

   Timer().schedule(object : TimerTask() {
            override fun run() {

                viewModel.updateNumber(num++)
            }
        }, 0, 2000)

原本的 ViewModel 是沒辦法自動更新 UI 的

    fun updateNum(num: Int) {

        this.num = num //沒作用
    }

讓 ViewModel 繼承 BaseObservable()
並在想要觀察的變數上面加上 Bindable 註解,這步就能夠將這個變數和 UI 層綁定在一起

class MainViewModel : BaseObservable() {

    @Bindable
    var num: Int = 0
}

最後在數據丟過來的地方呼叫 BaseObservable 的 notifyChange() 就成功囉

    fun updateNum(num: Int) {

        this.num = num
        notifyChange()
    }

這個 notifyChange() 是通知 databinding 把所有已綁定的數據更新一次,BaseObservable 還有另一個方法notifyPropertyChanged 是只用來更新某一個變數的

notifyPropertyChanged(BR.num)

這個 BR 不是指文湖線 是 databinding 自動生成的類似 R 檔用來放 id 的檔案,加上 @Bindable 註解的變數記得要 Make Project 後才會生成在 BR 檔裡面

    fun updateData(title: String, content: String) {

        this.content = content
        this.title = title

        notifyPropertyChanged(BR.title)//只有 title 會更新
    }

這個 notifyChange 很有似曾相識的感覺,很像 RecyclerView.Adapter 的 notifyDataSetChanged
為了不要每次更新時都要呼叫一次這個 fun ,databinding 很貼心的當我們設計了 ObservableField 這個類
這個類接的是一個泛型,只要把原本的變數包起來就可以不用再每次呼叫 notifyChange

var num = ObservableField<Int>()

原本的 assign 改成 set

this.num.set(num)

其他還有一些很類似的例如: ObservableBooleanObservableInt...都是大同小異的東西,可以視需求或是讓代碼更簡潔自行替換。

藉由這樣的操作,View 層只需要呼叫 ViewModel 改變數據,不需要接收任何數據更改完成的 callback
完成了先前提到的響應式 UI。

有任何問題或講得不清楚的地方歡迎留言和我討論。

更歡迎留言糾正我任何說錯的地方!

下一篇:Databinding (六) RecyclerView


上一篇
Day 11 Data Binding (四) BindingAdapter
下一篇
Day 13 Data Binding (六) RecyclerView
系列文
Android Architecture Components 學習心得筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言