活动和片段问题中的导航控制器
Posted
技术标签:
【中文标题】活动和片段问题中的导航控制器【英文标题】:NavController in Activity & Fragment Issue 【发布时间】:2021-05-05 18:30:59 【问题描述】:在我的Activity
中,我在OnCreate
中设置了NavController
:
navController = findNavController(this, R.id.NavHostFragment)
在我的Fragments
中,我在onViewCreated
中设置了NavController
:
navController = Navigation.findNavController(view)
Activity
仅在单击项目时从NavigationView
导航到几个Fragments
(例如SitesFragment
、ContactsFragment
、TasksFragment
等),如下所示:
R.id.nav_sites_fragment ->
navController.popBackStack(R.id.sitesFragment, true)
navController.navigate(R.id.sitesFragment)
在Fragments
中,点击事件(在RecyclerViews中主要指向其他Fragment,如SiteFragment
、ContactFragment
、TaskFragment
等)处理如下:
if (!navController.popBackStack(R.id.siteFragment, false))
// not in BackStack
navController.navigate(R.id.action_contactFragment_to_siteFragment)
问题是,即使我在Activity
操作中弹出BackStack,来自Fragment
操作的片段仍保留在后台堆栈中。..
我认为我对 backstack 的理解不正确,因为我不确定发生了什么 - 但也许我创建了两个独立的 NavController 实例?
编辑:虽然我看过这篇帖子How to clear navigation Stack after navigating to another fragment in android,但我仍然发现相同的行为。 Activity 中的 PopBackStack 没有清除添加到 backstack 的 Fragments..
例如:
SITES
-> SITE
-> CONTACT
-> CONTACTS
应该删除前三个片段,但 backpress 仍然返回到 CONTACT
..
【问题讨论】:
【参考方案1】:好的,所以我找到了这个帖子https://github.com/android/architecture-components-samples/issues/767。
我稍微修改了代码,在我的活动中我有以下功能:
private fun navigateWithClearStack(destination: Int)
val navController = findNavController(R.id.NavHostFragment)
val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(R.id.NavHostFragment) as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.business_navigation)
graph.startDestination = destination
navController.graph = graph
然后,我在哪里处理 NavigationView 点击:
override fun onNavigationItemSelected(item: MenuItem): Boolean
when (item.itemId)
R.id.nav_sites_fragment -> navigateWithClearStack(R.id.sitesFragment)
R.id.nav_projects_fragment -> navigateWithClearStack(R.id.projectsFragment)
R.id.nav_contacts_fragment -> navigateWithClearStack(R.id.contactsFragment)
R.id.nav_tasks_fragment -> navigateWithClearStack(R.id.tasksFragment)
R.id.nav_profile_fragment -> makeToast("Todo: Profile Fragment")
R.id.nav_settings_fragment -> makeToast("Todo: Settings Fragment")
business_drawer_layout.closeDrawer(GravityCompat.START)
return true
因此,当用户在应用程序中导航时,片段被添加到 BackStack(使用 popUpTo 处理重复项),但是当用户单击快捷方式回到“开始”片段之一时,图表被替换,从而清除 BackStack..我认为这很整洁。
【讨论】:
以上是关于活动和片段问题中的导航控制器的主要内容,如果未能解决你的问题,请参考以下文章