Android MVVM:RecyclerView

Evan Chen
Evan Android Note
Published in
6 min readJun 11, 2020

MVVM 系列:

這篇接著要來講MVVM在RecyclerView要注意的事情。我們要來做一個如下圖的RecyclerView裡面放一個TextView跟一個CheckBox。

MVVM一樣都是先建立ViewModel,接著跟repository取得資料後存在listLiveData裡。

RecyclerView裡item_layout.xml的DataBinding

以前在做Holder裡的資料繫結時,會在onBindViewHolder取出TextView在給值。

改成用DataBinding

在item_layout.xml 外層加上layout,裡面的data則放ViewModel及DataModel:item

接著設定android:text=”@{item.itemName}”

Adapter

在Constructor傳入ViewModel

在Holder的類別的constructor則是傳入ItemLayoutBinding。為什麼需要傳入ItemLayoutBinding是因為可能每個Holder會對映到不同的layout,還記得這個ItemLayoutBinding是從item_layout.xml自動產生出來的類別嗎。

在onBindViewHolder,則用position找到對映的item用來傳入binding裡。

回到Activity

當收到listLiveData的變動時,通知adapter.notifyDataSetChanged()

初始化資料

這個頁面被開啟後,就會跟Repository要資料。如果把取資料的方法viewModel.getData寫在onCreate裡,就會造成每次旋轉手機或更改設定時就會重新進入onCreate而再要一次資料,這也失去了我們用LiveData的目的。

所以取而代之的方式把取資料的方法寫在ViewModel的init裡,只在ViewModel被初始化時,去跟Repository要資料。

無資料時,用TextView顯示No Data

在ViewModel新增屬性empty,用來表示是否沒有資料。

回到activity_main.xml,就用viewModel.empty來控制RecyclerView與顯示無資料的FrameLayout哪個要顯示及隱藏。

Item的點擊

1.點擊該列可以開啟另一個Activity

2.選取Checkbox,SnackBar顯示哪個Item被選取

在以前的寫法,我們會建立一個Interface,從Adapter的Callback回到Activity。

而透過DataBinding,就直接讓CardView的onClick呼叫ViewModel.openItem方法。

在ViewModel,為了讓Activity可以知道這2個事件,我們建立了兩個Event

在Activity觀察openItemEvent,在這裡開啟另一個Activity。

在Activity觀察snackBarText,在這裡跳出SnackBar。

對於Activity,只需要知道收到跳出SnackBar的事件,而在Holder的Checkbox是點選跟Activity是沒有關系的。所以這裡的Event命名是用snackBarText,而不是像checkBoxEvent之類的。

總結一下RecyclerView的重點

  1. 初始化要取資料放在ViewModel的init。
  2. item_layout 也可以用Data Binding,減少Holder裡的程式碼
  3. 處理每一個Item的事件,不需要用Callback回到Activity,而是透過ViewModel的Event。

程式碼:https://github.com/evanchen76/RecyclerViewMVVM

下一篇:Fragment 共用 ViewModel

歡迎加入我的Facebook:Evan App Note

--

--