Я столкнулся с интересной проблемой при попытке выполнить динамическую или условную навигацию с помощью библиотеки Jetpack Navigation.
Я имею в виду цель - иметь возможность продолжать использовать 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
, я не могу.