iT邦幫忙

2026 iThome 鐵人賽

DAY 24
1

配合分支:day24/start,Repo: 按我

覺得怪嗎?那個人怎麼可以在那個地方,做那件事?察覺到了嗎?難不成那件事情違反了資料流?說的沒錯,資料流的確出了問題。

我說的就是這裡:

https://ithelp.ithome.com.tw/upload/images/20260912/20141615DJxKDSR15v.png

注意到了嗎?ViewModel 裡頭的資料怎麼在 ComposeView 修改了呢?這裡需要調整一下封裝,將更新某一則照片日記這件事,包裝成一個 setter。像這樣將 property 直接暴露出來不太好,不然隔壁的陳先生也可以隨時來修改。

狀態(State)更新很重要,盡量在 ViewModel 裡頭做更動未來也比較好追查。

將改變狀態包裝起來

仔細想,更新一篇照片日記會需要什麼資料呢?

  1. 需要知道是「哪一篇日記」
  2. 日記要改成什麼心情?

需要知道是「哪一篇日記」

在課程的前期有提到怎麼知道是同一篇日記? (如果忘記了,記得往前看。) 每次日記生成時,會設定這則日記的唯一 id,用這個 id 來查就能查到同一篇了。

所以這裡,需要 id。

日記要改成什麼心情?

簡單,在前面的課程之中已經將心情調整成 enum class,可以直接當成變數傳進來。

總結上述,這個 function 需要:updateMood(id: String, mood: Mood)
取得 id 去查哪一篇日記,需要更新成傳進來的心情。
先將日記變成一個 private property 以防忘記關門。

var entries by mutableStateOf(loadInitialEntries())
	private set  // 👈🏼 改成只有 private 能 set

接下來直接將 ComposeView 那一段程式碼接回 ViewModel 內部。

在那之前,之前漏掉介紹 map 這個 Kotlin collection 的內建 Function (也叫 API)。map 可以將吃進去的值,一個一個在 {} 內進行變化後吐回去。例如:

var numbers = listOf(1, 2, 3, 4)  // 👈🏼 [1, 2, 3, 4] 的列表

numbers = numbers.map { number -> // 👈🏼 一個一個丟出來
	number * 2 // 👈🏼 最後一行會回傳,這邊將每一個值都 * 2
}

// 最後 numbers = [2, 4, 6, 8]

弄懂 map 在幹嘛之後,這個 Function 就比較容易看懂:

https://ithelp.ithome.com.tw/upload/images/20260912/20141615LhroigyxHu.png

更新 UI

剛剛已經把 entries 關起來了,現在 PhotoDiaryApp 應該會開始抱怨啦。調整這邊結束後,今天的收尾就完成囉:

onMoodChange = { diaryId, selectedMood ->
	// 👇🏼 改由 ViewModel 修改即可
	viewModel.updateMood(diaryId, selectedMood)
}

上一篇
[Day23] 走火入魔的模樣
下一篇
[Day25] 再次修復資料流的錯誤
系列文
我的第一個手作りAndroid App!快樂學習物件導向程式設計!25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
chiaominchang222
iT邦新手 4 級 ‧ 2026-09-12 22:30:06

躺在床上卻還沒有寫24卻看到大家都寫好了是這樣的心情

早知道不要...

1
AndyAWD
iT邦研究生 5 級 ‧ 2026-09-12 23:48:25

今天狀態更新,明天該不會就是觀察者了吧

... 我討厭直覺敏銳的人

我要留言

立即登入留言