Lukasz Kalnik
11/25/2021, 3:39 PMdata class NameDialogState(val show: Boolean, val nameFieldValue: TextFieldValue)
val nameDialogState: StateFlow<NameDialogState>
The composable has a parameter for its UI state:
@Composable
fun NameDialog(uiState: State<NameDialogState>) {
if (uiState.value.show) {
AlertDialog(
// ...
text = TextField(value = uiState.value.nameFieldValue)
)
// ...
}
}
Inside the Fragment, the composable for the dialog takes the flow with collectAsState()
val uiState = viewModel.nameDialogState.collectAsState()
setContent {
NameDialog(uiState = uiState)
}
This works, but I wonder if it is possible to get rid of the State<*>
in the composable and use NameDialogState
directly, like this:
@Composable
fun NameDialog(uiState: NameDialogState)
All Google examples recommend injecting viewmodel directly into composable, which doesn't seem good architecture... I would like to keep the composables as "stupid" as possible.Adam Powell
11/25/2021, 3:56 PM[Mutable]State<T>
as parameters in API as it complicates usage for little to no benefit over the T
itself, or () -> T
if the goal is to defer reads to a narrower scope. Take many of the compose+viewmodel examples with a grain of salt, many of them are written for the audience of android developers who are familiar and comfortable with fragment+viewmodel+view patterns from android architecture components, and it's not always explicitly stated where an example's design decision is load-bearing in compose-centric surroundings or retained primarily to preserve that familiarity and bridge understanding. Asking, "do I really need this?" is always a good question. 🙂Lukasz Kalnik
11/25/2021, 4:00 PMState<T>
in my composable and use T
instead (which I confusingly named NameDialogState
, sorry for that).Adam Powell
11/25/2021, 4:01 PMState<T>
and use T
instead. 🙂Lukasz Kalnik
11/25/2021, 4:01 PMval uiState by viewModel.nameDialogState.collectAsState()
Then it's already unwrapped from the State<T>
into T
Lukasz Kalnik
11/25/2021, 4:01 PMAdam Powell
11/25/2021, 4:05 PMFlow<T>.collectAsState()
that is not @Composable
, so using that from the fragment won't workLukasz Kalnik
11/25/2021, 4:06 PMsetContent {}
Adam Powell
11/25/2021, 4:06 PMLukasz Kalnik
11/25/2021, 4:07 PMBerkeli Alashov
11/25/2021, 6:43 PMLukasz Kalnik
11/26/2021, 9:26 AM