The Navigation component works with the Android operating system to maintain the back stack as the user navigates in your app. In some cases, it might be helpful to maintain multiple back stacks at the same time, with the user moving back and forth between them. For example, if your app includes bottom navigation or a navigation drawer, multiple back stack support allows your users to switch freely between flows in your app without losing their place in any of them.
The Navigation component provides APIs that support multiple back stacks by saving and restoring the state of destinations in your navigation graph. The NavigationUI
class includes methods that handle this automatically, but you can also use the underlying APIs manually for a more customized implementation.
Implement support automatically with NavigationUI
The NavigationUI
class includes APIs that automatically save and restore the state of menu items as the user moves between them. These APIs implement multiple back stack support by default in the following cases:
- When you use the appropriate overload of
setupWithNavController()
to associate an instance ofNavigationView
orBottomNavigationView
with aNavController
instance, as described in Add a navigation drawer or Bottom navigation. - When you use
onNavDestinationSelected()
to create a custom navigation menu UI tied to destinations hosted by aNavController
instance.
These APIs require no further code changes to implement multiple back stack support, and are the recommended way of supporting multiple back stacks in your app.
Implement support manually with underlying APIs
If the elements provided by NavigationUI
don't satisfy your requirements, you can use the underlying APIs for saving and restoring back stacks through one of the other API surfaces provided by the Navigation component.
Navigation XML
In Navigation XML, <action>
elements in your navigation graph can use the app:popUpToSaveState
attribute to save the state of any destinations that the action popped using app:popUpTo
. They can also use the app:restoreState
attribute to restore any previously saved state for the destination defined in the app:destination
attribute.
You can use these attributes to support multiple back stacks. When a navigation action needs to move the user from one back stack to another, set both app:popUpToSaveState
and app:restoreState
to true
in the corresponding <action>
element. That way, the action saves the state of the current back stack while also restoring the previously saved state of the destination back stack, if it exists.
The following example shows an action that uses both of these attributes:
<action android:id=”@+id/swap_stack” app:destination=”@id/second_stack” app:restoreState=”true” app:popUpTo=”@id/first_stack_start_destination” app:popUpToSaveState=”true” />
NavOptions
The NavOptions
class allows you to pass special navigation options to save and restore back stacks when you navigate using a NavController
. This is true whether you create your instance of NavOptions
using the Kotlin DSL or using the NavOptions.Builder
:
Kotlin
// Use the navigate() method that takes a navOptions DSL Builder navController.navigate(selectedBottomNavRoute) { launchSingleTop = true restoreState = true popUpTo(navController.graph.findStartDestination().id) { saveState = true } }
Java
NavOptions navOptions = new NavOptions.Builder() .setLaunchSingleTop(true) .setRestoreState(true) .setPopUpTo(NavGraph.findStartDestination(navController.getGraph()).getId(), false, // inclusive true) // saveState .build(); navController.navigate(selectedBottomNavId, null, navOptions);
To learn more about passing navigation options, see Apply NavOptions programmatically.
Additional resources
To learn more about multiple back stack support with the Navigation component, see the following additional resources:
Blog posts
- MAD Skills: Navigation multiple back stacks on Medium
- Navigation: Multiple Back Stacks deep dive on Medium
Samples
- Now in Android app on GitHub
- Jetnews on GitHub
- Jetsnack on GitHub