Home » Android » android – Coordinate Back Button ownership in Nested Navigation Controllers

android – Coordinate Back Button ownership in Nested Navigation Controllers

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a main screen that shows the general information of the app, and a bottom sheet with additional information.

The main screen content can change if the user clicks something on the navigation drawer menu, selecting a new screen.

The bottom sheet on the main screen can also change as the user clicks for more data.

So I basically have a nested Navigation in the bottom sheet, which goes inside the main navigation in the main screen.

My problem is, when using the new Android Architecture Components Navigation Controller, there’s the app:defaultNavHost="true" option, which intercepts the back button.

This auto interception of the back button makes my user case pretty complicated. What I wanted is that when the user is in the main screen, the bottom sheet has control over the back button, and when the user swaps the main screen, than the main screen controls the back button.

Is it there a way to control the app:defaultNavHost programmatically, so nested Navigation Controllers can co-exist and coordinate back button ownership?

How to&Answers:

One of the fixes in Navigation 1.0.0-alpha04 is that Navigation automatically sets each Fragment destination as the primary navigation fragment, which ensures that any child fragment manager (such as the one used by a nested navigation graph) will automatically receive back button presses before the outer fragment manager.

This means that if you’re using a NavHostFragment with app:defaultNavHost="true" within another NavHostFragment that is also using app:defaultNavHost="true", it will work out of the box. The same thing would apply if you’re doing manually fragment transactions that add to the back stack using getChildFragmentManager() in any Fragment that was created by Navigation.

As explained in the original issue, app:defaultNavHost="true" is using the existing Fragment APIs and can be programmatically changed at any time by using code such as:

// This effectively removes the app:defaultNavHost flag
getSupportFragmentManager().beginTransaction()
    .setPrimaryNavigationFragment(null)
    .commit()
// Pass in your NavHostFragment to re-enable the flag