首页 > 解决方案 > How to navigate back in nested graph from the third level to the second level?

问题描述

I have a Single Activity project with Navigation Drawer. And I realized the navigation possibility by Navigation Components. I created a nav_graph.xml that can route and open each Fragment from the Navigation Drawer. And it is enough for one level routing. But my project has two and sometimes three-level routing. So I created a nested navigation graph for that nav_nested_settings.

<?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/nav_fragment_home">

    <fragment
        android:id="@+id/nav_fragment_home"
        android:name="com.app.ui.fragment.home.HomeFragment"
        android:label="@string/nav_home"
        tools:layout="@layout/fragment_home">
        // other actions ...
        <action
            android:id="@+id/action_nav_fragment_home_to_nav_fragment_fragment"
            app:destination="@id/nav_nested_settings" />
    </fragment>
    // ... other fragments
    <fragment
        android:id="@+id/nav_fragment_search"
        android:name="com.app.ui.fragment.search.SearchFragment"
        android:label="@string/nav_search"
        tools:layout="@layout/fragment_search" />
    <include app:graph="@navigation/nav_settings" />
</navigation>

and the nested graph is:

<?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:tool="http://schemas.android.com/tools"
    android:id="@+id/nav_nested_settings"
    android:label="@string/nav_settings"
    app:startDestination="@id/nav_fragment_settings">
    <fragment
        android:id="@+id/nav_fragment_settings"
        android:name="com.app.ui.fragment.settings.main.SettingsFragment"
        android:label="@string/nav_settings"
        tool:layout="@layout/fragment_settings">
        <action
            android:id="@+id/action_nav_fragment_settings_to_nav_fragment_settings_ads"
            app:destination="@id/nav_fragment_settings_ads" />
        <action
            android:id="@+id/action_nav_fragment_settings_to_nav_fragment_settings_app"
            app:destination="@id/nav_fragment_settings_app" />
        <action
            android:id="@+id/action_nav_fragment_settings_to_nav_fragment_settings_home"
            app:destination="@id/nav_fragment_settings_home" />
    </fragment>
    <fragment
        android:id="@+id/nav_fragment_settings_ads"
        android:name="com.app.ui.fragment.settings.ads.SettingsAdsFragment"
        android:label="@string/nav_settings_ads"
        tool:layout="@layout/fragment_settings_ads" />
    <fragment
        android:id="@+id/nav_fragment_settings_app"
        android:name="com.app.ui.fragment.settings.app.SettingsAppFragment"
        android:label="@string/nav_settings_app"
        tool:layout="@layout/fragment_settings_app" />
    <fragment
        android:id="@+id/nav_fragment_settings_home"
        android:name="com.app.ui.fragment.settings.home.SettingsHomeFragment"
        android:label="@string/nav_settings_home"
        tool:layout="@layout/fragment_settings_home">
    </fragment>
</navigation>

If I choose Settings from Navigation Drawer the app opens it. And then I click on ads / app / home button and the opens the next Fragment. But If I click back button or arrow in the app toolbar - nothing is happening.

How to solve that issue? How to navigate back in nested graph from the third level to the second level?

upd 01 // added function that sets up the NavController and AppBarConfiguration

private fun initNavigation() {
        mNavController = findNavController(R.id.navHostFragment)
        navView.setupWithNavController(mNavController)
        mAppBarConfiguration = AppBarConfiguration(mNavController.graph, drawerLayout)
        setupActionBarWithNavController(mNavController, mAppBarConfiguration)
}

upd02 I have found one helpful thing/bug. The back button is working fine without any additional code. But when I click on the back button the app repeats the previous action "go from SettingsFragment to SettingsAdsFragment", for example. I use moxy lib with default strategy - AddToEndSingleStrategy.

标签: androidandroid-fragmentsnavigationandroid-architecture-navigation

解决方案


从您的评论来看,我认为您onSupportNavigateUp()的说法并不完全正确。我已经用 navDrawer 和导航实现了几个应用程序,我覆盖的方式onSupportNavigateUp()如下:

// the activity hosting your navigation
class HostActivity : AppCompatActivity {
    // flag if for the currently shown fragment, navigating up is enabled
    // should be false for top level fragments, i.e. those accessible from navDrawer
    // should be set to true for lower level fragments
    private var canNavigateUp: Boolean = false
    
    ...

    override fun onSupportNavigateUp(): Boolean {
        return if (canNavigateUp) {
            mNavController.navigateUp()
        } else {
            NavigationUI.navigateUp(mNavController, mAppBarConfiguration)
        }
    }

    fun setNavigation(navigateUpEnabled: Boolean) {
        supportActionBar?.let { actionBar ->
            canNavigateUp = navigateUpEnabled
            if (navigateUpEnabled) {
                // set up icon
                actionBar.setHomeAsUpIndicator(null)
                lockUnlockDrawer(lock = true)
            } else {
                // set drawer icon
                actionBar.setDisplayShowHomeEnabled(true)
                lockUnlockDrawer(lock = false)
            }
        }
    }
}

然后,对于顶级片段,即可以直接从 navDrawer 访问的片段:

class TopLevelFragment : Fragment() {
    ...
    
    override fun onResume() {
        super.onResume()
        (activity as? HostActivity)?.setNavigation(false)
    }
}

对于较低级别的片段(ads/app/home):

class LowLevelFragment : Fragment() {
    ...
    
    override fun onResume() {
        super.onResume()
        (activity as? HostActivity)?.setNavigation(true)
    }
}

假设您已正确设置mNavController,这应该可以工作。mAppBarConfiguration


推荐阅读