iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Software Development

從 Fragment 到 Compose — 老 Android App 重寫的架構取捨系列 第 14 篇

Day 14|拆一個 1,700 行的 ViewModel:`combine` 取代屏障

  • 分享至 

  • xImage
  •  

動筆前先答(兩題)

答完再往下讀。進文章的答案從這兩題挑;答案寫在「你的回答」下面,寫完自己 commit。

1.【預測再驗證|架構論述】 舊的任務列表把「這一筆有沒有被勾選」寫成任務物件上的 var,由列表的 Adapter 直接改。假設換成 StateFlow 之後,有人照舊這樣寫:

data class TaskRow(val id: Long, val address: String, var selected: Boolean = false)

val rows = MutableStateFlow(listOf(TaskRow(1, "A"), TaskRow(2, "B")))

// 三種「勾選第 1 筆」的寫法
fun selectA() { rows.value[0].selected = true; rows.value = rows.value }
fun selectB() { rows.value[0].selected = true; rows.value = rows.value.toList() }
fun selectC() { rows.update { list -> list.map { if (it.id == 1L) it.copy(selected = true) else it } } }

三種寫法各自呼叫之後,正在收集 rows 的一方會不會收到新的值?它先前收到的那份清單裡,第 1 筆的 selected 是多少?先寫下預測與理由,再用 Turbine 寫一個測試驗證,三種寫法各從一份新的 rows 開始。最後判斷:勾選該不該放在任務物件上?如果不放,要放在哪裡?列表畫面需要的「任務+是否勾選」又要怎麼組出來?

我的回答:
(待補)

2.【決策邊界|UI 與版型】 本篇的任務列表一次載入當天的全部任務。假設要加一個「歷史任務」畫面:可以查過去一年、上萬筆的任務;每一列的高度依內容而定,地址長的那一列就比較高;使用者可以在列表上直接改備註、刪掉一筆。在什麼條件下,你會從「一次全載」改成分頁載入?分頁之後,刪掉已載入的第 3 頁裡的一筆,你會整份重抓、讓分頁來源失效後重抓,還是在已載入的資料上疊一層本機的修改?各自的代價是什麼?還沒載到的列如果先畫佔位列,你會維持「列高依內容」,還是改成固定列高?為什麼?

我的回答:
(待補)


上一篇
Day 13|多型 JSON:kotlinx.serialization 的 sealed 多型
下一篇
Day 15|拖曳排序:樂觀更新與回滾
系列文
從 Fragment 到 Compose — 老 Android App 重寫的架構取捨 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言