I have a navigation graph containing a HomeScreen
and a MyBottomSheet
. For bottom sheets I am using Accompanist Navigation.
Both of the destinations share a common ViewModel which is scoped to that navigation graph. From that ViewModel I am exposing a Flow<MyEvent>
where MyEvent
is:
sealed interface MyEvent
object MyEvent1: MyEvent
object MyEvent2: MyEvent
The two composables look like this:
@Composable
fun HomeScreen(viewModel: MyViewModel) {
LaunchedEffect(Unit) {
viewModel.eventsFlow.collect {
if(it is Event1) {
handleEvent1()
}
}
}
...
}
@Composable
fun MyBottomSheet(viewModel: MyViewModel) {
LaunchedEffect(Unit) {
viewModel.eventsFlow.collect {
if(it is Event2) {
handleEvent2()
}
}
}
...
}
Note that I want HomeScreen
to handle Event1
and MyBottomSheet
to handle Event2
(these events are basically navigation events).
The problem is that when MyBottomSheet
is visible, both the composables are collecting the flow at the same time because of which Event2
also gets collected by HomeScreen
. What I want is that when MyBottomSheet
is the topmost destination in back stack, HomeScreen
shouldn't be collecting flow. One of the possible solutions in my mind is:
@Composable
fun HomeScreen(viewModel: MyViewModel) {
LaunchedEffect(isHomeScreenOnTheTopOfBackStack) {
if(isHomeScreenOnTheTopOfBackStack) {
viewModel.eventsFlow.collect {
if(it is Event1) {
handleEvent1()
}
}
}
}
...
}
Now here, how can I check if HomeScreen
is on top of the back stack or not?
Or is there a better way to approach this problem?
Turned out it was quite easy. We can use navController.currentBackStackEntryAsState()
in the nav graph and pass the Boolean to the HomeScreen
.
composable("home") {
val isOnTop = navController.currentBackStackEntryAsState().value?.destination?.route == "home"
HomeScreen(
viewModel = //,
isHomeScreenOnTheTopOfBackStack = isOnTop
)
}