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

如何在Jetpack Compose中基于登录状态实现条件嵌套导航

在Jetpack Compose中实现基于Room的认证状态校验与条件导航

1. 定义导航路由

首先用密封类统一管理导航页面的路由,方便后续跳转控制:

sealed class Screen(val route: String) {
    object Splash : Screen("splash") // 状态加载过渡页
    object Login : Screen("login")   // 未登录时的登录页
    object Home : Screen("home")     // 已登录后的主页
}

2. 核心导航逻辑实现

在导航宿主组件中,通过collectAsState监听SessionManager的状态变化,根据状态自动跳转对应页面:

@Composable
fun MainNavigation(sessionManager: SessionManager) {
    val navController = rememberNavController()
    val sessionState by sessionManager.sessionState.collectAsState()

    NavHost(navController = navController, startDestination = Screen.Splash.route) {
        // 过渡加载页
        composable(Screen.Splash.route) {
            SplashScreen()

            // 监听状态变化,触发导航
            LaunchedEffect(sessionState) {
                when (sessionState) {
                    SessionState.Loading -> {
                        // 保持在过渡页,等待状态加载完成
                    }
                    SessionState.Active -> {
                        navController.navigate(Screen.Home.route) {
                            // 清除回退栈,避免返回过渡页或登录页
                            popUpTo(Screen.Splash.route) { inclusive = true }
                        }
                    }
                    SessionState.InActive -> {
                        navController.navigate(Screen.Login.route) {
                            popUpTo(Screen.Splash.route) { inclusive = true }
                        }
                    }
                }
            }
        }

        // 登录页
        composable(Screen.Login.route) {
            LoginScreen(
                onLoginSuccess = {
                    // 登录成功后更新会话状态
                    sessionManager.updateSession(SessionState.Active)
                }
            )
        }

        // 主页
        composable(Screen.Home.route) {
            HomeScreen(
                onLogout = {
                    // 登出后更新会话状态
                    sessionManager.updateSession(SessionState.InActive)
                }
            )
        }
    }
}

3. 完善SessionManager的状态更新能力

你的现有代码只处理了初始状态加载,需要补充登录/登出后的状态同步逻辑,同时修复异常处理(避免直接抛异常导致崩溃):

class SessionManager(
    private val sessionRepo: SessionRepository,
    private val coroutineScope: CoroutineScope
) {
    private val _sessionState = MutableStateFlow(SessionState.Loading)
    val sessionState: StateFlow<SessionState> = _sessionState

    init {
        coroutineScope.launch {
            sessionRepo.getActiveSession()
                .collect { resource ->
                    _sessionState.value = when (resource) {
                        is Resource.Success -> {
                            if (resource.data == null) SessionState.InActive else SessionState.Active
                        }
                        is Resource.Error -> {
                            // 加载失败默认设为未登录状态,避免崩溃
                            SessionState.InActive
                        }
                        is Resource.Loading -> SessionState.Loading
                    }
                }
        }
    }

    // 登录/登出时调用,同步Room数据与状态流
    fun updateSession(newState: SessionState) {
        coroutineScope.launch {
            when (newState) {
                SessionState.Active -> sessionRepo.saveActiveSession(/* 传入会话数据 */)
                SessionState.InActive -> sessionRepo.clearActiveSession()
                SessionState.Loading -> {} // 无需处理
            }
            // 触发重新加载会话,确保状态流与Room数据同步
            sessionRepo.getActiveSession().first()
        }
    }
}

4. 简单实现过渡加载页

@Composable
fun SplashScreen() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        CircularProgressIndicator()
    }
}

可选:处理错误状态

如果需要更精细的错误处理,可以扩展SessionState增加错误类型:

sealed class SessionState {
    object Loading : SessionState()
    object Active : SessionState()
    object InActive : SessionState()
    data class Error(val message: String) : SessionState()
}

然后在状态收集和导航逻辑中添加错误分支的处理(比如显示错误提示后跳转到登录页)。

内容的提问来源于stack exchange,提问作者Emmanuel Mtali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:36:17