How to handle back button when at the starting destination of the navigation component

onbackpressedcallback
how to use back button in android studio
onbackpresseddispatcher
back button navigation in fragment android
onbackpressed kotlin
android fragment back button example
on back pressed android
custom back button android

I've started working with the new navigation component and I'm really digging it! I do have one issue though - How am I supposed to handle the back button when I'm at the starting destination of the graph?

This is the code I'm using now:

findNavController(this, R.id.my_nav_host_fragment)
                .navigateUp()

When I'm anywhere on my graph, it's working great, it send me back, but when I'm at the start of it - the app crashes since the backstack is empty.

This all makes sense to me, I'm just not sure how to handle it.

While I can check if the current fragment's ID is the same as the one that I know to be the root of the graph, I'm looking for a more elegant solution like some bool flag of wether or not the current location in the graph is the starting location or not.

Ideas?

You shouldn't override "onBackPressed", you should override "onSupportNavigateUp" and put there

findNavController(this, R.id.my_nav_host_fragment)
            .navigateUp()

From the official documentation: You will also overwrite AppCompatActivity.onSupportNavigateUp() and call NavController.navigateUp

https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing

Handling back button in Android Navigation Component, And implemented it by all fragments that need to handle back button. Navigation component idea(letting the android handle the navigation). will handle back actions initiated by the the back arrow // at the start of the toolbar. toolbar. Define the following interface and implement it in all navigation destination fragments The Navigation editor uses a house icon to indicate the start destination. Once you have all of your destinations in place, you can choose a start destination by doing the following: In the Design tab, click on the destination to highlight it. Click the Assign start destination button . Alternatively, you can right-click on the destination and click Set as Start Destination. Connect destinations

I had a similar scenario where I wanted to finish the activity when I was at the start destination and do a regular 'navigateUp' when I was further down the navigation graph. I solved this through a simple extension function:

fun NavController.navigateUpOrFinish(activity: AppCompatActivity): Boolean {
return if (navigateUp()) {
    true
} else {
    activity.finish()
    true
}

}

And then call it like:

override fun onSupportNavigateUp() = 
        findNavController(R.id.nav_fragment).navigateUpOrFinish(this)

However I was unable to use NavigationUI as this would hide the back arrow whenever I was at the start destination. So instead of:

NavigationUI.setupActionBarWithNavController(this, controller)

I manually controlled the home icon:

setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_navigation_back)

Provide custom back navigation, All Android devices provide a Back button for this type of navigation, Android maintains a back stack of destinations as the user navigates The constructor for OnBackPressedCallback takes a boolean for the initial enabled state. the callback's handleOnBackPressed() to handle the Back button event. With each navigation action, a destination is added to the back stack. If you were to navigate repeatedly through this flow, your back stack would then contain multiple sets of each destination (A, B, C, A, B, C, A, and so on).

Override onBackPressed in your activity and check if the current destination is the start destination or not.

Practically it looks like this:

@Override
public void onBackPressed() {
    if (Navigation.findNavController(this,R.id.nav_host_fragment)
            .getCurrentDestination().getId() == R.id.your_start_destination) {
        // handle back button the way you want here
        return;
    }
    super.onBackPressed();
}

Interact programmatically with the Navigation component, Programmatically create and interact with certain navigation elements. lets your NavHost intercept system Back button presses. Starting with Navigation 2.2.0, you can get a reference to the NavBackStackEntry for any When the associated destination is popped off the back stack, the Lifecycle is destroyed, the state is  When you press the Back button, the current destination is popped off the top of the back stack, and you then navigate to the previous destination. The Up button appears in the app bar at the top of the screen. Within your app's task, the Up and Back buttons behave identically. The Up button never exits your app. If a user is at the app's start destination, then the Up button does not appear, because the Up button never exits the app. The Back button, however, is shown and does exit the app.

If you mean the start of your "root" navigation graph (just incase you have nested navigation graphs) then you shouldn't be showing an up button at all, at least according to the navigation principles.

Navigate Back with Navigation Component - Michael Spitsin, As we all know, Google introduced Navigation Components some time ago. can be saved and restore, and fragment three contain a button to go back to the first one. Actually all basic navigation work starts, when you call NavController.​navigate . else super.navigate(destination, args, navOptions, navigatorExtras) By using the Navigation architecture component, you provide a consistent and predictable experience to users — hassle and boilerplate free. Getting Started. To use the Navigation architecture component, you must use Android Studio 3.2 or higher. Install it by following the instructions in our Beginning Android development tutorial.

As my back button works correctly, and using NavController.navigateUp() crashed on start destination back button. I have changed this code to something like this. Other possibility will be to just check if currentDestination == startDestination.id but I want to close Activity and go back to other Activity.

override fun onSupportNavigateUp() : Boolean {
        //return findNavController(R.id.wizard_nav_host_fragment).navigateUp()
        onBackPressed()
        return true
    }

Android JetPack: Navigation Architecture Component, Navigation Architecture Component was introduced with Android Jetpack to facilitate Aside from one-time setups, an app should have a fixed starting screen when started where the system back button and up button have distinct destinations. Nested graphs come in handy when dealing with these type of situations,  In the upper left hand side of the graph, under Destinations, you can see a reference to the NavHost activity in the form of layout_name (resource_id). Click the plus button near the top to add your fragments to this graph. The Navigation component refers to individual screens as destinations .

WTF, How to handle back button when at the starting destination of the navigation component - android-architecture-components. Congratulations!! You have successfully implemented a splash screen using Navigation Component! Bonus. We can also use the same functionality without using NavOptions in code which I prefer personally to make the code cleaner. we can keep java code untouched and instead mention the properties in the Navigation graph itself.

Navigation Architecture Component for the Rest of Us, Navigation component is a part of Android Jetpack Library. Every app should have a fixed start destination. activity, there's no back stack created by default for that activity making up and back buttons useless. of Navigation Component such as handling fragment transactions, Up and Back actions,  While destinations are usually Fragments representing specific screens, the Navigation Architecture Component supports other destination types: Activities Navigation graphs and subgraphs - when the destination is a graph or subgraph, you navigate to the starting destination of that graph or subgraph

Android Navigation Architecture Components: Introduction, It is easy to see that from the notesFragment (start destination) we can go to maintaining backstack, managing action bar and the nav drawer icon. When the Cancel Button is clicked, we pop back stack (navigate back up  You'll hook up the Navigate To Destination button to navigate to the flow_step_one_dest destination (which is a destination that is a FlowStepFragment): 1. Open HomeFragment.kt. 2. Hook up the navigate_destination_button in onViewCreated() HomeFragment.kt

Comments
  • Do you overriding "onBackPressed"?
  • Yeah, the code sample I've added is placed in the onBackPressed override
  • stackoverflow.com/questions/50577356/…
  • The official documentation says that the app:defaultNavHost="true" attribute ensures that your NavHostFragment intercepts the system Back button. It is not obvious from the documentation that you have to overwrite the AppCompatActivity.onSupportNavigateUp() method in order to support the app toolbar's back button. Thanks.
  • With getCurrentDestination() can set any functionality to any fragment based on their ids :) Thanks
  • The visual button isn't displayed - it's changed with the hamburger menu. I'm referring to the physical back button. How do I handle it?