0

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

当前导航设置

我目前在navController里面创建MainActifity

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)
        }
    }
}

然后我将它传递给NavHost拥有两个的NavGraphs

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 创建一个navControlleras a会很酷single,但这是不可能的,因为rememberNavController函数只能在 Composable 内部调用。

有没有解决这个问题的解决方案navController

4

1 回答 1

0

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

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

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

提供CompositionLocalProvider

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

然后在任何可组合的里面CompositionLocalProvider,你可以得到你的导航控制器LocalNavController.current

于 2022-01-07T03:51:13.667 回答