android - 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
.
解决方案
从您的评论来看,我认为您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
推荐阅读
- java - 如何禁止本地主机实例进行尤里卡注册
- jquery - 如何从对象的键创建单个数组
- c# - 标题:在 asp.net 核心中将数据发布为 application/x-www-form-urlencoded
- hyperledger-fabric - 如何通过对等节点 cli 与链代码(使用 composer 安装)进行交互?
- jenkins - 如何从访问 Jenkins 的位置获取系统属性?
- ms-access - 使用 Access 表单文本框从查询中的同一字段过滤多个值/条件
- r - 通过在每组中相交值来减少分组数据框
- regex - Delphi:在我的情况下如何使用 system.RegularExpressions?
- java - 如何在 int 中获得十位数
- mongodb - 如何形成 mongo 查询以从匹配条件的对象数组中获取特定字段