Jetpack Compose页面导航求助:登录页跳转及ViewModel数据处理
Jetpack Compose页面跳转结合ViewModel实现方案
要实现Compose页面间跳转并通过ViewModel管理数据,官方推荐使用Navigation Compose库,以下是完整的实现方案:
1. 添加依赖
首先在项目的build.gradle.kts(Module级别)中添加Navigation Compose和ViewModel相关依赖:
dependencies { // Navigation Compose核心库 implementation("androidx.navigation:navigation-compose:2.7.7") // ViewModel与Compose集成库 implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2") }
2. 定义导航路由
用密封类统一管理页面路由,避免硬编码字符串:
sealed class Screen(val route: String) { object Login : Screen("login_screen") object Home : Screen("home_screen") }
3. 创建LoginViewModel
将登录逻辑和数据存储在ViewModel中,符合MVVM架构:
import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel class LoginViewModel : ViewModel() { // 用户输入的用户名(可观察状态) val username = mutableStateOf("") // 登录状态标记 val isLoggedIn = mutableStateOf(false) // 登录逻辑处理 fun performLogin() { // 这里可以添加实际的登录验证逻辑(比如请求接口) isLoggedIn.value = username.value.isNotEmpty() // 示例:非空即视为登录成功 } }
4. 配置导航宿主与页面
通过NavHost管理页面路由,在登录页面触发跳转,同时共享ViewModel数据:
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @Composable fun AppNavigation() { val navController = rememberNavController() NavHost( navController = navController, startDestination = Screen.Login.route ) { // 登录页面路由 composable(Screen.Login.route) { val loginViewModel = viewModel<LoginViewModel>() LoginScreen( viewModel = loginViewModel, onLoginSuccess = { // 登录成功后跳转到首页 navController.navigate(Screen.Home.route) } ) } // 首页路由 composable(Screen.Home.route) { // 从登录页面的ViewModel获取共享数据 val loginViewModel = viewModel<LoginViewModel>() HomeScreen(username = loginViewModel.username.value) } } } @Composable fun LoginScreen( viewModel: LoginViewModel, onLoginSuccess: () -> Unit ) { Column( modifier = Modifier.fillMaxSize().padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { TextField( value = viewModel.username.value, onValueChange = { viewModel.username.value = it }, label = { Text("请输入用户名") } ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = { viewModel.performLogin() if (viewModel.isLoggedIn.value) { onLoginSuccess() } } ) { Text("登录") } } } @Composable fun HomeScreen(username: String) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = "欢迎回来,$username!") } }
关键说明
- ViewModel共享:通过
viewModel<LoginViewModel>()方法,在同一个导航图内的页面会自动共享同一个ViewModel实例,无需手动传递数据 - 跳转逻辑:使用
navController.navigate()实现页面跳转,若需要传递临时参数,可在路由中添加占位符(如"home_screen/{username}"),但ViewModel共享更适合持久化数据的传递 - 架构规范:登录逻辑放在ViewModel中,页面仅负责UI渲染和事件触发,符合MVVM的职责分离原则
内容的提问来源于stack exchange,提问作者Mihneas22
相关产品推荐
相关产品推荐

