You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose Navigation中startDestination异常,始终显示登录界面怎么修复?

问题:Compose Navigation始终显示登录界面的修复方案

用户编写了如下Compose导航代码,逻辑上可行,但实际运行时用户始终看到登录界面,需要修复:

@Composable
fun RootNav() {
    val navController = rememberNavController()
    val authViewModel: AuthViewModel = hiltViewModel()

    val authState by authViewModel.authState.collectAsState()
    val startDestination = when (authState) {
        is AuthState.Unauthenticated -> ScreenRoutes.AuthNav.route
        is AuthState.AuthenticatedWithoutCouple -> ScreenRoutes.RegisterNav.route
        is AuthState.AuthenticatedWithCouple -> ScreenRoutes.HomeNav.route
        else -> ScreenRoutes.AuthNav.route
    }
    NavHost(
        navController = navController,
        startDestination = startDestination
    ) {
        AuthNav(authViewModel, navController)

        RegisterNav(navController)

        composable(route = ScreenRoutes.HomeNav.route) {
            HomeNavGraph(navController){
                authViewModel.signOut()
            }
        }
    }
}

修复方案

1. 修正AuthState的初始值与初始化逻辑

问题根源之一可能是AuthState的初始值未正确设置,且ViewModel未在启动时主动检查用户登录状态。默认初始值如果是Unauthenticated,会直接导向登录页,后续即使异步获取到用户状态,也不会触发导航更新。

修改AuthViewModel,添加初始加载状态,并在初始化时检查当前用户:

class AuthViewModel @Inject constructor(
    private val authRepository: AuthRepository
) : ViewModel() {
    // 初始设为Loading状态,避免直接进入登录页
    private val _authState = MutableStateFlow<AuthState>(AuthState.Loading)
    val authState = _authState.asStateFlow()

    init {
        // 启动时立即检查用户认证状态
        checkCurrentAuthStatus()
    }

    private fun checkCurrentAuthStatus() {
        viewModelScope.launch {
            val currentUser = authRepository.getCurrentUser()
            _authState.value = when {
                currentUser == null -> AuthState.Unauthenticated
                authRepository.hasCoupleInfo(currentUser.id) -> AuthState.AuthenticatedWithCouple
                else -> AuthState.AuthenticatedWithoutCouple
            }
        }
    }
}

2. 动态监听AuthState变化,替换静态startDestination

原代码中startDestination仅在NavHost初始化时计算一次,后续authState更新不会触发导航变更。需要用LaunchedEffect监听状态变化,动态导航到对应页面:

修改RootNav代码:

@Composable
fun RootNav() {
    val navController = rememberNavController()
    val authViewModel: AuthViewModel = hiltViewModel()
    val authState by authViewModel.authState.collectAsState()

    // 监听authState变化,动态调整导航
    LaunchedEffect(authState) {
        val targetRoute = when (authState) {
            AuthState.Loading -> return@LaunchedEffect // 加载状态不跳转
            is AuthState.Unauthenticated -> ScreenRoutes.AuthNav.route
            is AuthState.AuthenticatedWithoutCouple -> ScreenRoutes.RegisterNav.route
            is AuthState.AuthenticatedWithCouple -> ScreenRoutes.HomeNav.route
        }

        // 避免重复导航,减少不必要的页面栈操作
        if (navController.currentDestination?.route != targetRoute) {
            navController.navigate(targetRoute) {
                popUpTo(navController.graph.startDestinationId) { inclusive = true }
            }
        }
    }

    NavHost(
        navController = navController,
        startDestination = ScreenRoutes.Loading.route // 初始显示加载页
    ) {
        // 新增加载页,给用户明确的加载反馈
        composable(ScreenRoutes.Loading.route) {
            LoadingScreen() // 自定义简单的加载UI,比如CircularProgressIndicator
        }

        AuthNav(authViewModel, navController)
        RegisterNav(navController)
        composable(route = ScreenRoutes.HomeNav.route) {
            HomeNavGraph(navController){
                authViewModel.signOut()
            }
        }
    }
}

3. 验证登录成功后的状态更新

确保用户登录成功时,AuthViewModel正确更新authState为AuthenticatedWithoutCouple或AuthenticatedWithCouple,触发LaunchedEffect的导航逻辑。例如登录方法:

fun login(email: String, password: String) {
    viewModelScope.launch {
        val result = authRepository.login(email, password)
        if (result.isSuccess) {
            checkCurrentAuthStatus() // 登录成功后重新检查状态,更新authState
        } else {
            // 处理登录失败逻辑
        }
    }
}

内容的提问来源于stack exchange,提问作者Talha K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:38:16