1.【模擬面試追問|持久化與離線】 舊的排序畫面有一個開關:打開時,每放下一筆任務,就把新順序送給後端,後端會重排其他任務再回傳;等待回應的期間,整個列表鎖住不能拖。新版想改成樂觀更新:放下的當下就更新畫面,請求在背景送,失敗就回滾。面試官順著這個設計往下追問:
我的回答:
我覺得回滾要回到第 3 次的成功回應,從新。為了達到這目的,需要記住所有請求的結果(回應是否失敗)。以及請求的順序。
後端是唯一事實來源,畫面要照後端成功回傳的重排順序。如果回應到達時,使用者正在拖第 4 次,則優先更新列表,放棄使用者的第 4 次拖移排序。
App 被系統回收後,背景執行緒取消了。重開之後,畫面該顯示請求送出時的原本列表順序。
2.【預測再驗證|UI 與版型】 用 LazyColumn 做拖曳排序。把第 1 筆拖到第 3 筆的位置時,ViewModel 交換清單元素,發出一份新的清單。每一列裡有一個「展開備註」的狀態:
@Composable
fun TaskRow(task: Task) {
var expanded by remember { mutableStateOf(false) }
// 點一下切換 expanded,展開時多顯示一段備註
}
// A:沒有 key
LazyColumn { items(tasks) { task -> TaskRow(task) } }
// B:用任務 id 當 key
LazyColumn { items(tasks, key = { it.id }) { task -> TaskRow(task) } }
使用者先展開第 1 筆的備註,再把它拖到第 3 筆的位置。A、B 各自拖完之後,展開的是畫面上的哪一列?在列上加了 Modifier.animateItem() 時,A、B 有沒有移動的動畫?先寫下預測與理由,再用 Compose UI 測試(或 Preview 的互動模式)驗證。最後判斷:key 用任務 id 就夠了嗎?如果同一張訂單可能在列表出現兩次(例如取件、送件各一筆),key 要怎麼定?
我的回答:
(待補)