Jetpack navigation: Title and back/up arrow in the action bar?

Damn Vegetables picture Damn Vegetables · Jul 8, 2018 · Viewed 14k times · Source

I have installed the latest canary version of Android Studio, and followed this (https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing) instruction to implement a simple two page navigation. Basically page1 has a button, and when it is clicked, the app shows page2.

It works, but there is one problem... It does not seem to do anything with the action bar automatically. Is it supposed to show up/back arrow and the "Label" attribute on the action bar automatically by the navigation library? Or am I supposed to do all the work manually as before? I want to show the back arrow and "Details" on action(tool) bar when page2 is showing.

On button click at page 1.

override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
    button1.setOnClickListener {
        val nav = NavHostFragment.findNavController(this);
        nav.navigate(R.id.show_page2)
    }
}

Main activity XML. By default it was the default Action Bar, I have replaced it with a ToolBar. There was no difference.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_height="?attr/actionBarSize"
        android:elevation="4dp"
        android:background="?attr/colorPrimary"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        android:layout_width="match_parent">
    </androidx.appcompat.widget.Toolbar>

    <fragment
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:navGraph="@navigation/nav_graph"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Nav graph XML.

<?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/nav_graph"
            app:startDestination="@id/page1">

    <activity
        android:id="@+id/mainActivity2"
        android:name="com.android.navtest.MainActivity"
        android:label="activity_main"
        tools:layout="@layout/activity_main"/>
    <fragment
        android:id="@+id/page1"
        android:name="com.android.navtest.BlankFragment2"
        android:label="Home page"
        tools:layout="@layout/page1">
        <action
            android:id="@+id/show_page2"
            app:destination="@id/page2"
            app:enterAnim="@anim/anim1"
            app:popExitAnim="@anim/anim2"/>
    </fragment>
    <fragment
        android:id="@+id/page2"
        android:name="com.android.navtest.BlankFragment"
        android:label="Details"
        tools:layout="@layout/page2"/>
</navigation>

Answer

ianhanniballake picture ianhanniballake · Jul 8, 2018

You can connect your ActionBar to a NavController using NavigationUI.setupActionBarWithNavController(). This is generally done in your Activity, right after you call setSupportActionBar():

supportActionBar = findViewById<Toolbar>(R.id.toolbar)

// Get the NavController for your NavHostFragment
val navController = findNavController(R.id.nav_host_fragment)

// Set up the ActionBar to stay in sync with the NavController
setupActionBarWithNavController(navController)

This approach is covered in the Navigation talk at Google I/O 2018.