In all the examples I have seen with view models in combination with Jetpack Compose, one usually stores a state in the view model as MutableStateFlow and then applies collectAsState in the compose function in order to get a Compose state.
My question: Why not store the state directly in the view model, and not some flow? E.g.
class MyViewModel: ViewModel() {
val showDialog = mutableStateOf(false)
}
@Compose
fun MyScreen(viewModel: MyViewModel) {
Button(onClick = { viewModel.showDialog = true })
if (viewModel.showDialog) {
AlertDialog(...)
}
}
The above code seems to run as intended. Is this a valid solution then?
Yes it certainly is. I don't know where you saw those examples, but this is indeed the recommended practice. You can check the State
Codelab; it demonstrates how to replace the LiveData
objects to mutableStateOf
inside the viewmodel
. Also, as far as the usage of LiveData
and Flow
is concerned, it is mainly for interoperability, as far as I know. The apps which are not fully built in Compose, but are being transferred, or apps which plan to use the view system alongside Compose. mutableStateOf
is only for Jetpack compose and hence, developers will want to use LiveData
in such cases. However, if you are building a brand new project, and want it to be composed of only Compose, then definitely go for what you've mentioned in the question. It is the correct way.
Using mutableStateOf()
in a view model will work, but this is no longer the best approach.
If you look at the latest version of the official documentation, including the Now in Android reference app, view models should stay data-centric and therefore use the data-centric MutableStateFlow
instead of the Compose-centric mutableStateOf()
.
Android Developer Guide – Foundation: Screen UI state
Android Developer Guide – App Architecture: Mutating the UI state from background threads
Now in Android – View Model
Now in Android - Screen
Using MutableStateFlow
also makes much more sense from a unit test perspective. When testing a view model in isolation, any dependency on Compose (or other UI-centric packages and classes) should be a red flag. In other words, why would you need any Compose dependencies when testing a view model?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With