今天的文章中,我們要來介紹如何將 ViewModel
expose 的可觀察資料型態接到 Composable 上。我們會示範將 DiaryViewModel
裡的 StateFlow
,接到 DiaryScreen
Composable,來顯示「日記清單」。
此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!
立馬下載
DiaryViewModel.kt
裡面有個 diaries StateFlow
(已初始化為 diaryRepository.getDiaries
)。
我們希望每當有新資料 emit 到 diaries StateFlow
時,Diary
composable 中的 UI 都會更新。我們可以使用 StateFlow.collectAsState()
函式。在 composable function 中使用 collectAsState()
時,會從 StateFlow
collect value,並使用 Compose 的 State
API 來將最新的值存起來。這樣會讓讀取該狀態值的 composable 在 StateFlow
emit value 時進行 recompose。
在 DiaryScreen
composable 將 assign diaries
的那行程式碼替換為呼叫 ViewModel
裡面 diaries
property 的 collectAsState
:
import androidx.compose.runtime.collectAsState
@Composable
fun DiaryScreen(
modifier: Modifier = Modifier,
viewModel: DiaryViewModel = viewModel(),
) {
val diaries by viewModel.diaries.collectAsState()
// ...
}
重新把 app 跑起來,畫面就會顯示「日記清單」。
Compose 也有提供其他可觀察資料型態的 API:
LiveData.observeAsState()
androidx.compose.runtime:runtime-livedata:$composeVersion
Observable.subscribeAsState()
androidx.compose.runtime:runtime-rxjava2:$composeVersion
、androidx.compose.runtime:runtime-rxjava3:$composeVersion
我們來探討上面這段 code 一些可觀察資料型態的生命週期。
DiaryScreen
composable 上的 diaries
變數:因為定義在 DiaryScreen
composable 內,所以生命週期會 follow DiaryScreen
的 Composition。當 DiaryScreen
被移出 Composition 時,diaries
變數就會被清掉。也會停止 collect StateFlow
DiaryViewModel
裡的 diaries
StateFlow
:因為定義在 DiaryViewModel
內,所以生命週期 follow DiaryViewModel
。當沒有人觀察這個 StateFlow
時,就會終止資料流。當 DiaryViewModel
死掉時,diaries
StateFlow
也會被清掉。此系列文章是以我的業餘專案:Kimoji 為範例。
Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!
立馬下載
Reference: https://developer.android.com/codelabs/jetpack-compose-advanced-state-side-effects