Arpit Shukla
11/09/2021, 11:11 AMC1
which collects an event Flow from a view model. C1
calls another composable C2
passing some data and lambdas. C2
contains a Scaffold.
Now when my ViewModel sends an event of showing a snackbar (after doing some validation when user clicked a button), I want to pass that event to C2
. How can I do this?Zoltan Demant
11/09/2021, 11:26 AMcollectLatest
so that a new prompt overrides the previous one right away, but you can use collect if youd like to show them one by one. The rememberUpdatedState is just so that the same LaunchedEffect block runs continiously, instead of a new one spinning up everytime a new prompt is available. The collectLatest
shows the snackbar, and notifies my viewmodel that the prompt has been consumed so that the state is cleared of it.
val updatedPrompt by rememberUpdatedState(prompt)
LaunchedEffect(Unit) {
snapshotFlow { updatedPrompt }
.filterNotNull()
.collectLatest { current ->
when (current) {
is SomeMessage -> {
// Show snackbar, notify to clear prompt
}
}
}
}
Arpit Shukla
11/09/2021, 11:32 AMC1
or C2
(composables in my question)?Zoltan Demant
11/09/2021, 11:47 AMArpit Shukla
11/09/2021, 11:49 AMC1
and have to show the snackbar from another composable C2
.Zoltan Demant
11/09/2021, 12:05 PMC2
somehow, in my example I would pass in the prompt. You can then use something like my code above to consume it and actually show the snackbar!Albert Chang
11/09/2021, 1:45 PM@Composable
fun C1(eventFlow: Flow<String>) {
val scaffoldState = rememberScaffoldState()
LaunchedEffect(eventFlow, scaffoldState) {
eventFlow.collectLatest { message ->
scaffoldState.snackbarHostState.showSnackbar(message)
}
}
C2(scaffoldState = scaffoldState)
}
@Composable
fun C2(scaffoldState: ScaffoldState) {
Scaffold(scaffoldState = scaffoldState) {
// content
}
}
Adam Powell
11/09/2021, 1:58 PMArpit Shukla
11/09/2021, 2:11 PMAdam Powell
11/09/2021, 7:05 PMSnackbarState
is defined to allow for this; the snackbar host will dismiss the specific message after the timeout. In terms of sticking around longer, arguably that's not a problem. After the screen reconfigures in a config change the user is often a bit disoriented anyway, a couple seconds more of seeing a message that they might otherwise miss isn't necessarily a negative experience. Something you could handle the timeout in a ViewModel scope or something with instead if you were so inclined but I wouldn't bother in my own code.