Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display back button on toolbar on first screen of navigation graph

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.

like image 802
Abhiroop Avatar asked May 02 '19 11:05

Abhiroop


2 Answers

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.

like image 74
dhabensky Avatar answered Sep 16 '22 14:09

dhabensky


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;
    }
like image 32
尹劍平 Avatar answered Sep 19 '22 14:09

尹劍平