I start to use the Navigation Components library and created a graph to navigation between different fragments. My basic setup is a BottomNavigationView with two Fragments (A and B). Fragment B can go deeper inside graph to Fragment C and Fragment C goes to Fragment D. Everythings works at this point and the back stack goes from D -> C -> B.
My problem is Fragment Z which is accessible from a toolbar menu defined on the activity and used by every Fragment. What i want is a path from A -> B -> C -> D -> Z and by pressing the back button i want to go one step back to Fragment D. But i go to the start of my graph which is Fragment A.
Fragment Z uses no actions. The Navigation Component detects the same fragment.id inside navigation graph and menu.xml and does the navigation for me. So an can't define some multi back stack magic for me.
navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<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/fragmentA">
<fragment android:id="@+id/fragmentA" />
<fragment android:id="@+id/fragmentZ" />
<fragment
android:id="@+id/fragmentB">
<action
android:id="@+id/action_b_to_c"
app:destination="@id/fragmentC" />
</fragment>
<fragment
android:id="@+id/fragmentC">
<action
android:id="@+id/action_c_to_d"
app:destination="@id/fragmentD" />
</fragment>
</navigation>
toolbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/fragmentZ"
android:title="Go to Z"
app:showAsAction="always" />
</menu>
bottom_navigation.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/fragmentA"
android:title="Go to A" />
<item
android:id="@+id/fragmentB"
android:title="Go to B" />
</group>
</menu>
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView( R.layout.activity_main )
val toolbar: MaterialToolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
val navView: BottomNavigationView = findViewById( R.id.bottomNavigation )
navView.setupWithNavController( navController )
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_toolbar, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
}
NavigationUI.onNavDestinationSelected()
reads:
By default, the back stack will be popped back to the navigation graph's start destination.
Menu items that have android:menuCategory="secondary"
will not pop the back stack.
Also see: Navigation and the back stack.