如何使用Jetpack导航创建动态/条件导航?

问题描述 投票:0回答:1

我在尝试使用Jetpack导航库完成动态或条件导航时遇到了一个有趣的问题。

我想到的目标是能够继续使用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?")
    }
}

呼叫站点示例

navigate(
        dynamicNav.navigateToDashboard(
                mapOf(
                        Pair(R.id.dashboardFragment, PhoneVerificationFragmentDirections.phoneVerificationToDashboard()),
                        Pair(R.id.dashboardV2Fragment, PhoneVerificationFragmentDirections.phoneVerificationToDashboardV2())
                )
        )
)

navigate(
        dynamicNav.navigateToDashboard(
                mapOf(
                        Pair(R.id.dashboardFragment, EmailLoginFragmentDirections.emailLoginToDashboard()),
                        Pair(R.id.dashboardV2Fragment, EmailLoginFragmentDirections.emailLoginToDashboardV2())
                )
        )
)

查看呼叫站点,您会发现问题出在哪里。如果我想添加一个新的潜在目的地,比方说dashboardV3Fragment,那么我必须去每个呼叫站点并添加另一个Pair

这几乎破坏了具有DynamicNavImpl类的目的。所以这就是我被困住的地方。我希望能够封装决定要去哪里的目标所涉及的各种变量,但是似乎NavDirections的实现方式却无法实现。

android android-architecture-components android-jetpack android-jetpack-navigation
1个回答
0
投票

我经历了几种不同的方法,并且发现了一些仍然不理想的东西,但是可以用于我的用例。

我完全放弃了使用中央动态导航管理器的想法。相反,我决定使用一个“重定向”或“容器” Fragment来决定要显示什么Fragment

所以这是DashboardRedirectFragment内的新代码>

childFragmentManager.beginTransaction().replace(
                R.id.dashboard_placeholder,
                if (featureFlagService.isDashboardV2Enabled()) {
                    DashboardV2Fragment.newInstance()
                } else {
                    DashboardFragment.newInstance()
                }
        ).commit()

我使用此方法的方式是在我的导航图中注册一个名为dashboardRedirectFragment的新目标,而该图中需要访问仪表板的任何内容都将使用dashboardRedirectFragment目标。

这将动态导航逻辑完全封装在重定向Fragment中,并允许我继续按预期使用导航图。

© www.soinside.com 2019 - 2024. All rights reserved.