如何在嵌套图中从第三级导航回第二级



我有一个带有Navigation DrawerSingle Activity项目。并通过Navigation Components实现了导航的可能性。我创建了一个nav_graph.xml,它可以从Navigation Drawer路由并打开每个Fragment。这对于一级路由来说已经足够了。但我的项目有两个,有时还有三个路由。因此,我为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>

嵌套图为:

<?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>

如果我从Navigation Drawer中选择Settings,应用程序会打开它。然后我单击ads/app/home按钮,打开下一个Fragment。但如果我单击应用程序工具栏中的back按钮或箭头,则不会发生任何事情。

如何解决这个问题?如何在嵌套图中从第三级导航回第二级?

upd 01//添加了设置NavController和AppBarConfiguration 的功能

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

upd02我发现了一个有用的东西/错误。后退按钮工作正常,没有任何附加代码。但当我点击后退按钮时,应用程序会重复上一个动作";从设置碎片到设置碎片";,例如我使用默认策略为AddToEndSingleStrategy的moxy-lib。

根据您的评论,我认为您的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)
}
}

对于较低级别的片段(广告/应用程序/主页(:

class LowLevelFragment : Fragment() {
...

override fun onResume() {
super.onResume()
(activity as? HostActivity)?.setNavigation(true)
}
}

假设您正确设置了mNavControllermAppBarConfiguration,这应该会起作用。

我找到了解决方案!

我应该对Moxy库使用正确的策略。是的,我在主题中没有提到这个lib,因为我不认为它会破坏应用程序流。

接口方法的旧策略类型

StateStrategyType(AddToEndSingleStrategy::class)
interface SettingsView : BaseMvpView {
fun showManageAdsFragment()
fun showManageAppUIFragment()
fun showManageHomeUIFragment()
}

接口方法的新策略类型

StateStrategyType(SkipStrategy::class)
interface SettingsView : BaseMvpView {
fun showManageAdsFragment()
fun showManageAppUIFragment()
fun showManageHomeUIFragment()
}

最新更新