'jetpack navigation -> multiple back stack with bottom navigation not working when back stack is cleared
Starting with version 2.4.0-alpha01, the NavigationUI helpers support multiple back stacks without any code change. If your app uses the setupWithNavController() methods for BottomNavigationView or NavigationView, all you need to do is to update the dependencies and multiple back stack support will be enabled by default.
In my aplication I have "Intro" screen.(TestFragment)
When user clicks on the button, app is navigating to home screen where Bottom navigation is present.
When navigating from "Intro screen" I want to clear back stack.
<fragment
android:id="@+id/testFragment"
android:name="com.example.android.navigationadvancedsample.TestFragment"
android:label="Test" >
<action
app:popUpToInclusive="true"
app:popUpTo="@id/testFragment"
android:id="@+id/action_test_to_title"
app:destination="@id/titleScreen" />
</fragment>
In this situation multiple back stack funcionality is not working. There is just one back stack. However when property popUpToInclusive is set to false multiple back stack are present and everything is working as expected!
bottom_nav.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/titleScreen"
android:icon="@drawable/ic_home"
android:contentDescription="@string/cd_home"
android:title="@string/title_home" />
<item
android:id="@+id/leaderboard"
android:icon="@drawable/ic_list"
android:contentDescription="@string/cd_list"
android:title="@string/title_list" />
<item
android:id="@+id/register"
android:icon="@drawable/ic_feedback"
android:contentDescription="@string/cd_form"
android:title="@string/title_register" />
</menu>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.navigationadvancedsample.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav"/>
</LinearLayout>
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = supportFragmentManager.findFragmentById(
R.id.nav_host_container
) as NavHostFragment
navController = navHostFragment.navController
// Setup the bottom navigation view with navController
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
bottomNavigationView.setupWithNavController(navController)
// Setup the ActionBar with navController and 3 top level destinations
appBarConfiguration = AppBarConfiguration(
setOf(R.id.titleScreen, R.id.leaderboard, R.id.register)
)
setupActionBarWithNavController(navController, appBarConfiguration)
}
nav_graph.xml
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@+id/testFragment">
<fragment
android:id="@+id/titleScreen"
android:name="com.example.android.navigationadvancedsample.homescreen.Title"
android:label="@string/title_home">
<action
android:id="@+id/action_title_to_about"
app:destination="@id/aboutScreen"/>
</fragment>
<fragment
android:id="@+id/aboutScreen"
android:name="com.example.android.navigationadvancedsample.homescreen.About"
android:label="@string/title_about" />
<fragment
android:id="@+id/leaderboard"
android:name="com.example.android.navigationadvancedsample.listscreen.Leaderboard"
android:label="@string/title_list">
<action
android:id="@+id/action_leaderboard_to_userProfile"
app:destination="@id/userProfile"/>
</fragment>
<fragment
android:id="@+id/userProfile"
android:name="com.example.android.navigationadvancedsample.listscreen.UserProfile"
android:label="@string/title_detail">
<deepLink
android:id="@+id/deepLink"
app:uri="www.example.com/user/{userName}"
android:autoVerify="true"/>
<argument
android:name="userName"
app:argType="string"/>
</fragment>
<fragment
android:id="@+id/register"
android:name="com.example.android.navigationadvancedsample.formscreen.Register"
android:label="@string/title_register">
<action
android:id="@+id/action_register_to_registered"
app:destination="@id/registered"/>
</fragment>
<fragment
android:id="@+id/registered"
android:name="com.example.android.navigationadvancedsample.formscreen.Registered"
android:label="Registered" />
<fragment
android:id="@+id/testFragment"
android:name="com.example.android.navigationadvancedsample.TestFragment"
android:label="Test" >
<action
app:popUpToInclusive="false"
app:popUpTo="@id/testFragment"
android:id="@+id/action_test_to_title"
app:destination="@id/titleScreen" />
</fragment>
</navigation>
Why multiple back stack are not supported when navigating from another fragment and clearing back stack? Maybe this is a bug in the jetpack navigation library.
Solution 1:[1]
I recently walkthrough to your code and found that in your nav_graph.xml you defined testFragment as startDestination, this is the start point of your application, so when you are on welcome screen that you have bottomNavigationView, when you click on the back button, it will return to testFragment Screen, if your app is single activity (single page application) you have to implement OnBackPressedCallback on the first fragment of your welcome screen, some sample code:
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
NavBackStackEntry backStackEntry =
getNavController().getPreviousBackStackEntry();
if (backStackEntry != null) {
NavDestination destination = backStackEntry.getDestination();
if (destination != null) {
if (destination.getId() == R.id.homeFragment) {
requireActivity().finish();
}
}
}
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(callback);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | OneDev |


