Step #4: Teaching Navigation About the App Bar
Google, however, is not happy.
Google wants apps to have “up navigation”. This involves having a back arrow visible in the Toolbar
when the user is somewhere deeper in the navigation graph than the start destination, such as being on our DisplayFragment
:
(if you are wondering why this is called “up navigation” when the arrow points to the side… well, that’s complicated…)
To make Google happy, we need to add a few things to our MainActivity
, so that the Navigation component knows about the app bar and can add the up navigation icon when needed.
First, in MainActivity
, add this property:
private lateinit var appBarConfiguration: AppBarConfiguration
An AppBarConfiguration
is… a configuration for our app bar. In this app, our Toolbar
will serve as our app bar.
(if you are wondering why we have action bars, toolbars, and app bars… well, that’s complicated…)
Next, add this block of code to the end of the onCreate()
function in MainActivity
:
supportFragmentManager.findFragmentById(R.id.nav_host)?.findNavController()?.let { nav ->
appBarConfiguration = AppBarConfiguration(nav.graph)
setupActionBarWithNavController(nav, appBarConfiguration)
}
To get our NavController
, we need to call findNavController()
on something. Unfortunately, Google made that relatively complex when you are using FragmentContainerView
for these fragments. We need to:
- Get a
FragmentManager
by referencingsupportFragmentManager
- Find our
NavHostFragment
in there by callingfindFragmentById()
and passing in the ID of ourFragmentContainerView
(R.id.nav_host
) - Call
findNavController()
on thatFragment
We then:
- Create an
AppBarConfiguration
for the navigation graph managed by thatNavController
- Call
setupActionBarWithNavController()
, to tell the Navigation component that we want it to automatically update the app bar based on our navigation through our navigation graph
Finally, add this function to MainActivity
:
override fun onSupportNavigateUp() =
navigateUp(findNavController(R.id.nav_host), appBarConfiguration)
When the user taps that arrow in the app bar, this function will be called. Here, we just pass that event along to the Navigation component, asking it to perform whatever would be appropriate for up navigation at this point. Here, it is safe for us to just use findNavController()
. The issues requiring us to go through the extra complexity to call findNavController()
up in onCreate()
are tied to that code being in onCreate()
, before the Navigation system has gotten everything wired up. By the time onSupportNavigateUp()
is called, Navigation is fully initialized and we can just use the simpler straightforward findNavController()
call.
If you run the app, not only will that arrow appear in the app bar when we are viewing the DisplayFragment
, but tapping it will return you to the RosterListFragment
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.