Navigation Compose: Saving bottomSheet’s state 🦸🏻‍♂️

theapache64
3 min readAug 15, 2021

At the time of writing this article, Navigation Material’s bottomSheetstate won’t be saved when you move to a normal destination.

Problem: BottomSheet’s state doesn’t maintained

To fix this, you can use the saveState ,restoreState and launchSingleTopfeature of the navigation-compose library.

Let’s see how we can do that.

First, let’s look at the current code

We’ve four destinations. A, B, C and D. A and D are normal destinations. B and C are bottomSheet destinations.

The navigation flow is as follows, A -> B -> C -> D -> go back .

The problem

When we go back from D, the app should go to C , then B and finally A , but rather, it goes to A directly without showing C and D

Solution

saveState ,restoreState and launchSingleTopto the rescue.

According to the official documentation,

saveState : Whether the back stack and the state of all destinations between the current destination and the NavOptionsBuilder.popUpTo ID should be saved for later restoration via NavOptionsBuilder.restoreState or the restoreState attribute using the same NavOptionsBuilder.popUpTo ID (note: this matching ID is true whether inclusive is true or false).

restoreState: Whether this navigation action should restore any state previously saved by PopUpToBuilder.saveState or the popUpToSaveState attribute. If no state was previously saved with the destination ID being navigated to, this has no effect.

launchSingleTop: Whether this navigation action should launch as single-top (i.e., there will be at most one copy of a given destination on the top of the back stack).This functions similarly to how FLAG_ACTIVITY_SINGLE_TOP works with activites.

You didn’t get it? No problem, let me simplify it 🤷🏼

saveState is a magical flag to tell your navController something like “Hey navController, when you pop these screens, I want you to save their state”.

restoreState will tell “Hey navController, when you navigate to this screen and if you have a state available for the screen, please restore it”

launchSingleTopwill tell “Hey navController, when you navigate to this screen, please don’t create a new instance if you’ve already one in your back stack”

With a combination of these three flags, we can restore navigation entries’ state.

Code Change

First, we need to update the area where C navigates to D

and then, change the go back logic in the D screen

That’s it.

Updated Code

Output

Demo: State maintained

--

--