iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0

https://ithelp.ithome.com.tw/upload/images/20220912/20151958IFjRs0xIZ4.png Medium 好讀版

此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 限免兌換碼

在昨天的文章中無法順利選取標籤的問題,解決方法有兩種:

  • 變更 Label data class 的定義,將 checkedState 的型態從 Boolean 改成 MutableState<Boolean>,這樣可以讓 Compose 觀察 item 的變化。
  • 複製要更改的 item,從 List 中移除這個 item,然後把變動過的 item 重新加入清單,讓 Compose 觀察清單變更內容。

這兩種方法各有優缺點。舉例來說,根據 List 實作方式的不同,移除並讀取 element 可能非常耗費資源。

建議避免讓操作 List 消耗太多資源,然後讓 checkedState 可被觀察,這樣做能夠提昇效能,也比較適合 Compose。

新的 Label 看起來可能會像這樣:

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf

data class Label(
  val id: Int, 
  val name: String, 
  val checked: MutableState<Boolean> = mutableStateOf(false)
)

我們可以使用 property delegate,讓變數 checked 更加簡潔。

Label 從 data class 改成 class。讓 Label 在 constructor 接收 initialChecked 變數,預設值為 false。接下來,我們就能用 mutableStateOf factory method 初始化 checked 變數,並把 initialChecked 當做預設值。

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue

data class Label(
  val id: Int, 
  val name: String, 
  initialChecked: Boolean = false
) {
    var checked by mutableStateOf(initialChecked)
}

大功告成!現在「多選標籤」能夠撐過 recomposition 和 configuration changes 了!

測試

因為我們將事務邏輯放進 ViewModel,而不是和 composable functions 耦合,這樣也讓 unit test 更容易進行了。

有興趣的話,可以進一步使用 instrumented test 確認 Compose 程式碼和 UI state 是否都能正常運作。

此系列文章是以我的業餘專案:Kimoji 為範例。

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 限免兌換碼

Reference: https://developer.android.com/codelabs/jetpack-compose-state


上一篇
Compose 實作清單多選
下一篇
從 ViewModel 使用可觀察的資料流
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言