The top-level composable in my Compose app is structured like this:
ModalBottomSheetLayout(/*...*/) {
Scaffold(
topBar = {
when (currentScreen) {
/*...*/
}
},
content = {
AppNavigation(navController)
},
bottomBar = {
// Bottom navigation
}
)
}
Since I am using BottomSheet
together with BottomNavigation
I cannot delegate handling the former to the screens from AppNavigation
because it will break Material Design guidelines (BottomSheet
will be shown above the BottomNavigation
).
Top bars of my screens are also separate from the screens themselves as per my other post
And of course since bottom sheet that is tied to a screen must reflect some state of this screen, we would like to share a ViewModel
between them. Same goes for the top bar.
The above restrictions necessarily mean that the instance of a desired ViewModel
must be created outside the scope of all mentioned composables and as such outside the NavHost
and its scoped ViewModelStore
s, which is a huge problem because the only other ViewModelStore
is the one owned by the Activity, which in a single-activity pattern is never cleared! So every shared ViewModel
effectively becomes a singleton and a memory leak, aside from weird bugs it causes (sate that needed to be updated by creating a new instance but wasn't). What I actually want is for shared view models to be destroyed when user leaves the screen it is tied to, but it doesn't seem possible.
So is this even possible to fix this problem without changing the structure of the UI (and such dealing with other problems that led to it in the first place)? Does it even needs fixing? Are singleton view models OK provided state-related bugs are fixed?