0

I am using the Android Navigation Architecture Components for navigating a Fragment-based-, Single-Activity-application. The main navigation is implemented via NavigationDrawer-pattern: DrawerLayout with NavigationView and NavHostFragment plus and additional Toolbar.

Everything is working fine so far - I am able to navigate to every Fragment -, except for the BackStack of the main-level Fragments. Any Fragment other than the startDestination seems to be added to the BackStack instead of being replaced like a regular NavigationDrawer would do.

The misbehavior can be identified via the Burger-icon that switches to a Back-icon as soon as I navigate to a Fragment other than the startDestination, and by navigating back which leads me to the startDestination instead of exiting the app.

How should the Navigation Architecture Components be used in order to replace the main Fragments in combination with a NavigationView?

I am initializing the Navigation Architecture Components like this:

class MainActivity : AppCompatActivity {

    private val navigationHostFragment: NavHostFragment
        get() = supportFragmentManager.findFragmentById(R.id.navigationHost) as NavHostFragment

    private val navigationController: NavController
        get() = navigationHostFragment.navController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity)

        // Views are bound via Kotlin Android Extensions
        setSupportActionBar(toolbar)
        NavigationUI.setupWithNavController(toolbar, navigationController, drawerLayout)
        NavigationUI.setupWithNavController(navigationView, navigationController)
    }

    override fun onSupportNavigateUp(): Boolean = findNavController(R.id.navigationHost).navigateUp()
}

The layout for the activity (/res/layout/activity.xml) looks like this:

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>

        <fragment
            android:id="@+id/navigationHost"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:navGraph="@navigation/navigation"
            app:defaultNavHost="true"/>

    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/navigation"/>

</androidx.drawerlayout.widget.DrawerLayout>

The navigation graph (/res/navigation/navigation.xml) looks like this:

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

    <fragment
        android:id="@+id/first"
        android:name="de.example.FirstFragment"
        android:label="@string/first"/>

    <fragment
        android:id="@+id/second"
        android:name="de.example.SecondFragment"
        android:label="@string/second"/>

</navigation>

The menu for the NavigationView (/res/menu/navigation.xml) looks like this:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">

        <item
            android:id="@+id/first"
            android:title="@string/first"/>

        <item
            android:id="@+id/second"
            android:title="@string/second"/>

    </group>

</menu>

The relevant dependencies look like this:

dependencies {
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.core:core-ktx:1.0.0'
    implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha06'
    implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha06'
}
  • you want to add all fragments in backstack? – Man Oct 18 '18 at 09:19
  • No, I do not want to add any Fragment to the BackStack in my example. Every Fragment should be replaced. – Philipp Fahlteich Oct 19 '18 at 11:04
  • What you trying to achieve is going against the navigation principle: "Apps have a fixed destination which is the screen the user sees when they launch your app from the launcher. This destination should also be the last screen the user sees when they return to the launcher after pressing the back button." https://developer.android.com/topic/libraries/architecture/navigation/navigation-principles – Alex Oct 24 '18 at 12:28
  • I understand, this makes sense. Thank you for your response and have a great day! – Philipp Fahlteich Oct 25 '18 at 13:04

1 Answers1

1

As Alex posted, my original goal clashes with the Principles of Navigation:

Apps have a fixed destination which is the screen the user sees when they launch your app from the launcher. This destination should also be the last screen the user sees when they return to the launcher after pressing the back button.