I'm trying out androidx navigation component and have setup my activity with a toolbar a container. I'm doing this in one of the intermittent screens of my app which has a lot of internal navigation/steps and I thought I could navigation arch component a try with this.
Since this is an intermittent screen, I want to display a back button on the toolbar from the first screen itself.
I've already setup the toolbar with the below code in the onCreate() method of my host activity,
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
NavigationUI.setupActionBarWithNavController(this, navHostFragment.getNavController());
I can see the back button/back arrow on the second screen of my graph but not on the first screen.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/listing">
<fragment
android:id="@+id/listing"
android:name=".ui.ItemsListingFragment"
android:label="Items"
tools:layout="@layout/items_listing" >
<action
android:id="@+id/listToQuantity"
app:destination="@id/quantity"
/>
<action
android:id="@+id/listToReason"
app:destination="@id/reason"
/>
</fragment>
<fragment
android:id="@+id/quantity"
android:name=".ui.ItemQuanitySelectionFragment"
android:label="Items"
tools:layout="@layout/fragment_item_quanity_selection" >
<action
android:id="@+id/quantityToReason"
app:destination="@id/reason"
/>
</fragment>
<fragment
android:id="@+id/reason"
android:name=".ui.ItemReasonFragment"
android:label="Items"
tools:layout="@layout/fragment_item_reason">
</fragment>
</navigation>
What more changes do I need to make to add the back button on the toolbar right from the first step.
As you noted, navigation component show back button on all destinations except top-level. It uses an AppBarConfiguration
to determine which destinations are considered 'top-level'.
So you need to:
1) create AppBarConfiguration without top-level destinations
2) call a 3-argument version of setupActionBarWithNavController
AppBarConfiguration abc = new AppBarConfiguration.Builder().build();
NavigationUI.setupActionBarWithNavController(this, navHostFragment.getNavController(), abc)
To customise up button behavior on 'top-level' destination you can set fallback OnNavigateUpListener
in your appbar configuration builder:
new AppBarConfiguration.Builder().setFallbackOnNavigateUpListener(listener).build()
More info from sources:
click on up button calles NavigationUI.navigateUp(NavController, AppBarConfiguration)
which in turn calles NavController.navigateUp()
which tries to pop the backstack. As it cannot pop back stack, it just does nothing and returns false. Your fallback listener will be called in that case.
The back button is displayed as onSupportNavigateUp()
method return true
.
You need to override onSupportNavigateUp()
method.
@Override
protected void onCreate(Bundle savedInstanceState) {
//
setSupportActionBar(mToolbar)
mNavController = getNavController();
mAppBarConfiguration = new AppBarConfiguration.Builder().build();
NavigationUI.setupActionBarWithNavController(this, mNavController, mAppBarConfiguration);
}
@Override
public boolean onSupportNavigateUp() {
//
if (!(mNavController.navigateUp() || super.onSupportNavigateUp())) {
onBackPressed();
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With