0

I am using compose in Android. For UI states I use stateFlow in viewmodel & for handling bottom sheet show hide state, I use sharedFlow.
The issue is for sharedFlow collect code in UI, it has to be put inside LaunchedEffect which gets executed at the end.
So cases where from init of viewmodel if I emit a value to sharedFlow like showing bottom sheet those value gets missed. I don't want to use repeat 1 as there are many other handlings which I'll have to do.
Is there any easier way to do it?

LaunchedEffect(key1 = true) {
        viewModel.showBottomSheet.collect {
            when (it) {
                true -> scope.launch {
                    bottomSheetState.show()
                }

                false -> scope.launch {
                    bottomSheetState.hide()
                }
            }
        }
    }

In viewmodel I have a code something similar to this

private val _showBottomSheet = MutableSharedFlow<Boolean>()
val showBottomSheet = _showBottomSheet.asSharedFlow()

One ugly hack is add some delay before updating the value for such cases. Can someone suggest a better way

1 Answers1

0

You should pass your event (show/hide bottom sheet) as part of the state. Modify your state to be as shown here

data class MyState(
    // other stuff
    val showBottomSheet: Boolean,
)

and initialize it as necessary (set it to true initially if that's what your requirements specify).

Then in your UI you read the showBottomSheet flag as you read the rest of the state and, if it's true, display the bottom sheet. When you dismiss the bottom sheet, call a method in your viewmodel that toggles the flag back to false.

Francesc
  • 25,014
  • 10
  • 66
  • 84
  • When bottom sheet is automatically dismissed, this also I will have to track & update manually right ? – Ujjwal Kumar Maharana Aug 31 '23 at 16:23
  • Yes,, a bottom sheet dialog has a onDismissRequest where you would call the viewmodel to notify of this event. – Francesc Aug 31 '23 at 16:27
  • when (bottomSheetStateHolder.showBottomSheet) { true -> { scope.launch { bottomSheetState.showSheet() } } false -> { scope.launch { bottomSheetState.hideSheet() } } } Here scope.launch can only be done inside a LanchedEffect. How can I handle that – Ujjwal Kumar Maharana Aug 31 '23 at 16:49