Jetpack 撰写了如何集中导航控制器并注入它



我目前在我的应用程序中有两个NavGraphs,一个用于身份验证路由,如登录和注册,另一个用于登录时的主页路由.
我目前需要将navController作为参数传递到每个可组合项中,当我想使用它时。这绝对是不可扩展的,所以我想知道是否可以使其可注入,以便我可以通过像Koin这样的 DI 框架请求它。我目前正在我的应用程序中使用Koin,所以如果我可以使用它的依赖注入工具,将navController作为singleton注入,那就太好了。

当前导航设置

我目前在MainActifity内创建navController

class MainActivity : AppCompatActivity() {
private lateinit var navController: NavHostController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startKoin {
androidLogger(if (BuildConfig.DEBUG) Level.ERROR else Level.NONE)
androidContext(this@MainActivity)
modules(listOf(networkModule, viewModelModule, interactorsModule))
}
setContent {
navController = rememberAnimatedNavController()
SetupNavGraph(navController = navController)
}
}
}

然后我把它传递到保存两个NavGraphsNavHost

fun SetupNavGraph(
navController: NavHostController
) {
AnimatedNavHost(
navController = navController,
startDestination = AUTH_GRAPH_ROUTE,
route = ROOT_GRAPH_ROUTE
) {
homeNavGraph(navController = navController)
authNavGraph(navController = navController)
}
}

以下是我对所有身份验证路由NavGraph。我还NavController作为参数传递,以便我可以在屏幕内使用它。

fun NavGraphBuilder.authNavGraph(
navController: NavController
) {
navigation(
startDestination = Screen.Login.route,
route = AUTH_GRAPH_ROUTE
) {
composable(
Screen.Login.route,
) {
val loginViewModel: LoginViewModel = getViewModel()
LoginScreen(
navController = navController,
state = loginViewModel.state.value,
onTriggerEvent = loginViewModel::onTriggerEvent
)
}
composable(
Screen.Register.route,
) {
val registerViewModel: RegisterViewModel = getViewModel()
RegisterScreen(
navController = navController,
state = registerViewModel.state.value,
onTriggerEvent = registerViewModel::onTriggerEvent
)
}
}
}

登录时所有页面的NavGraph类似于我的身份验证,因此不值得显示。

如果我可以通过 Koin 创建一个navController作为single,那就太酷了,但这是不可能的rememberNavController因为该函数只能在可组合对象中调用。

有没有解决方案来解决将navController传递到每个嵌套可组合项的问题?

为了便于测试/预览,建议仅传递处理程序而不是导航控制器本身,并在调用处理程序时在SetupNavGraph内执行所有实际导航。更多信息可以在这里找到。

如果它不适合您,您可以创建自己的合成本地,如下所示:

val LocalNavController = compositionLocalOf<NavHostController> {
error("No LocalNavController provided")
}

提供CompositionLocalProvider

setContent {
CompositionLocalProvider(LocalNavController provides rememberAnimatedNavController()) {
SetupNavGraph()
}
}

然后在CompositionLocalProvider内部的任何可组合中,你可以得到带有LocalNavController.current的导航控制器。

最新更新