Android 如何使用Jetpack导航创建动态/条件导航?
在使用Jetpack导航库实现动态或条件导航时,我遇到了一个有趣的问题 我的目标是能够继续使用Android 如何使用Jetpack导航创建动态/条件导航?,android,android-architecture-components,android-jetpack,android-jetpack-navigation,Android,Android Architecture Components,Android Jetpack,Android Jetpack Navigation,在使用Jetpack导航库实现动态或条件导航时,我遇到了一个有趣的问题 我的目标是能够继续使用nav_graph.xml来管理整个导航图,但同时允许基于某些因素的条件导航 我在下面包含了一些代码,这些代码显示了我的解决方案的发展方向。问题在于,它本质上需要大量维护,以便将来的条件逻辑能够工作 我确实希望示例中的navigateToDashboard函数能够在没有参数或很少更改的参数的情况下执行。例如,不是传递NavDirections,而是传递一些标识符,让navigateToDashboard
nav_graph.xml
来管理整个导航图,但同时允许基于某些因素的条件导航
我在下面包含了一些代码,这些代码显示了我的解决方案的发展方向。问题在于,它本质上需要大量维护,以便将来的条件逻辑能够工作
我确实希望示例中的navigateToDashboard
函数能够在没有参数或很少更改的参数的情况下执行。例如,不是传递NavDirections
,而是传递一些标识符,让navigateToDashboard
函数知道返回哪个NavDirections
管理条件逻辑的类的代码
class DynamicNavImpl(private val featureFlagService: FeatureFlagService) : DynamicNav {
override fun navigateToDashboard(navDirectionsMap: Map<Int, NavDirections>): NavDirections {
val destinationIdRes = if (featureFlagService.isDashboardV2Enabled()) {
R.id.dashboardV2Fragment
} else {
R.id.dashboardFragment
}
return navDirectionsMap[destinationIdRes] ?: handleNavDirectionsException(destinationIdRes)
}
private fun handleNavDirectionsException(destinationIdRes: Int): Nothing {
throw IllegalStateException("Destination $destinationIdRes does not have an accompanying set of NavDirections. Are you sure you added NavDirections for it?")
}
}
查看呼叫站点,您会发现这可能会有问题。如果我想添加一个新的潜在目的地,比如说仪表板v3fragment
,那么我必须到每个呼叫站点添加另一个对
这几乎违背了使用DynamicNavImpl
类的目的。这就是我被困的地方。我希望能够封装决定去哪个目的地所涉及的各种变量,但就NavDirections
的实现方式而言,我无法做到。我尝试了几种不同的方法,最终找到了一种仍然不理想但适合我的用例的方法
我完全放弃了使用中央动态导航管理器的想法。相反,我决定使用一个“重定向”或“容器”Fragment
来决定要显示的Fragment
下面是仪表板重定向片段中的新代码
childFragmentManager.beginTransaction().replace(
R.id.dashboard_placeholder,
if (featureFlagService.isDashboardV2Enabled()) {
DashboardV2Fragment.newInstance()
} else {
DashboardFragment.newInstance()
}
).commit()
我使用它的方式是在我的导航图中注册一个名为dashboardRedirectFragment
的新目的地,并且图形中需要访问仪表板的任何内容都使用dashboardRedirectFragment
目的地
这完全封装了重定向片段中的动态导航逻辑,并允许我按照预期继续使用导航图
navigate(
dynamicNav.navigateToDashboard(
mapOf(
Pair(R.id.dashboardFragment, EmailLoginFragmentDirections.emailLoginToDashboard()),
Pair(R.id.dashboardV2Fragment, EmailLoginFragmentDirections.emailLoginToDashboardV2())
)
)
)
childFragmentManager.beginTransaction().replace(
R.id.dashboard_placeholder,
if (featureFlagService.isDashboardV2Enabled()) {
DashboardV2Fragment.newInstance()
} else {
DashboardFragment.newInstance()
}
).commit()