相关疑难解决方法(0)

ViewModel 使用 JetpackCompose 触发导航

在 Android 中,我经常想要导航以响应 ViewModel 的状态更改。(例如,成功的身份验证会触发导航到用户的主屏幕。)

最佳实践是从 ViewModel 内触发导航吗?是否有有意的机制来触发可组合项中的导航以响应 ViewModel 状态更改?

使用 Jetpack Compose 处理此用例的过程并不明显。如果我尝试类似以下示例的操作,将会发生导航,但我导航到的目的地将无法正常运行。我相信这是因为在调用导航之前不允许完成原始的可组合函数。

// Does not behave correctly.
@Composable fun AuthScreen() {
    val screenState = viewModel.screenState.observeAsState()
    if(screenState.value is ScreenState.UserAuthenticated){
        navController.navigate("/gameScreen")
    } else {
        LoginScreen()
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 LaunchedEffect ,我确实会观察到正确的行为,如下所示:

// Does behave correctly.
@Composable fun AuthScreen() {
    val screenState = viewModel.screenState.observeAsState()
    if(screenState.value is ScreenState.UserAuthenticated){
        LaunchedEffect(key1 = "test") {
            navController.navigate("$/gameScreen")
        }
    } else {
        LoginScreen()
    }
}
Run Code Online (Sandbox Code Playgroud)

它是否正确?LaunchedEffect 的文档说明如下,但我并不是 100% 清楚其含义:

当 LaunchedEffect 进入组合时,它将启动块到组合的 CoroutineContext 中。当 LaunchedEffect 用不同的 key1、key2 或 …

android android-jetpack-compose jetpack-compose-navigation compose-recomposition

5
推荐指数
1
解决办法
1319
查看次数

Jetpack Compose Navigation 无限加载屏幕

我正在尝试Navigation使用单个活动和多个Composable屏幕来实现。

这是我的NavHost

@Composable
@ExperimentalFoundationApi
fun MyNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = HOME.route,
    viewModelProvider: ViewModelProvider,
    speech: SpeechHelper
) = NavHost(
    modifier = modifier,
    navController = navController,
    startDestination = startDestination
) {
    composable(route = HOME.route) {
        with(viewModelProvider[HomeViewModel::class.java]) {
            HomeScreen(
                speech = speech,
                viewModel = this,
                modifier = Modifier.onKeyEvent { handleKeyEvent(it, this) }
            ) {
                navController.navigateTo(it)
            }
        }
    }

    composable(route = Destination.VOLUME_SETTINGS.route) {
        VolumeSettingsScreen(
            viewModelProvider[VolumeSettingsViewModel::class.java]
        ) { navController.navigateUp() }
    }
} …
Run Code Online (Sandbox Code Playgroud)

android infinite-loop android-jetpack-compose jetpack-compose-navigation compose-recomposition

4
推荐指数
1
解决办法
1879
查看次数