配合分支:day22/start,Repo: 按我
來做搜尋日記的功能,日記的列表是這個 Function 給的:
fun getDisplayEntries(): List<DiaryEntry> {}
只要更動讀取的 entries 就可以改變排序,這個前幾章已經做過了。只要對這邊動手腳就能製作出「搜尋」的效果。
如果覺得疑惑,為何調整這裡就可以達到搜尋的效果,可以自行跑一次「資料流」來確認。
這些都是 View 層級(跟畫面有關的)的更動,也就是:ComposeView、ViewModel。
欲搜尋需要有關鍵字,先在 ViewModel 新增關鍵字。
// getter
var searchQuery by mutableStateOf("")
private set
// setter
fun updateSearchQuery(query: String) {
searchQuery = query
}
由 Code 可知列表從 getDisplayEntries() 調整。而內容,則可以用 Kotlin 內建的 filter 方法,來過濾列表裡頭的資料。

外面都不用改,因為回傳的內容沒有變。
日記的列表,也就是 DiaryList ,加入一個打字框:

調整了 UI 內容後,將資料流完整。資料怎麼送進來,怎麼 callback。

接著在 UI 的最上面,可以摸到 ViewModel 的地方,將資料流接起來。
searchQuery = viewModel.searchQuery,
onSearchQueryChange = { query -> viewModel.updateSearchQuery(query) },

配合分支:day22/search,Repo: 按我
來都來了,乾脆也做上透過心情來過濾照片日記。這一塊的資料流完全與上面相同,預期做的行為會非常類似。
起手式要紀錄使用者選擇的心情(Day 21 已經調整成 enum class 啦),同樣調整 PhotoDiaryViewModel.kt ,將 Mood 的 setter 和 getter 設定好。
// getter
var selectedMoodFilter by mutableStateOf<Mood?>(null)
private set
// setter
fun updateMoodFilter(mood: Mood?) {
selectedMoodFilter = mood
}
一樣來調整 getDisplayEntries(),別忘了所有照片日記都是來自於這邊。(專有名詞是 Single Source of Truth)。

資料源搞定後,剩下的就只剩下 UI 的工而已。
一樣在日記的列表,也就是 DiaryList 加入下拉式選單元件。

有了這個下拉式選單元件之後,加在 DiaryList 之中。這時需要將 DiaryList 與 ViewModel 串接上,這樣資料流才會完整。
串接的方式和輸入框幾乎一模一樣,故這次就由讀者自行試試吧(解答都在 GitHub Repo)!最後完成的畫面會像是:
