Jetpack Compose中如何将ScreenA的phoneNumberState值传递到ScreenB
Compose 跨页面传参最简实现方案
直接用Navigation组件自带的路由参数能力即可,不需要额外引入ViewModel或其他依赖,总共修改3处代码就能跑通:
1. 修改导航路由配置
给ScreenB的路由添加参数占位,跳转时自动解析传递的值,修改后的Navigation代码如下:
@OptIn(ExperimentalPagerApi::class) @Composable fun Navigation( startDestination: String ) { val navController = rememberNavController() NavHost(navController = navController, startDestination = startDestination) { composable("screenA" ) { ScreenA(navController = navController) } // 修改点:路由添加{phoneNumber}参数占位 composable("screenB/{phoneNumber}") { backStackEntry -> // 从导航栈中取出传递的手机号参数,空值给默认空串兜底 val receivePhoneNumber = backStackEntry.arguments?.getString("phoneNumber") ?: "" ScreenB(navController = navController, phoneNumber = receivePhoneNumber) } } }
2. 修改ScreenA提交按钮的跳转逻辑
在按钮的onClick回调里,把输入的手机号拼接在路由后跳转,代码如下:
Button( modifier = Modifier .width(285.dp) .height(55.dp), onClick = { // 可先加手机号格式校验、非空校验,校验通过再跳转 val inputPhone = phoneNumberState.value.trim() if (inputPhone.isNotBlank()) { navController.navigate("screenB/$inputPhone") } }, colors = ButtonDefaults.buttonColors( backgroundColor = color ), shape = RoundedCornerShape(40), ) { Text( text = "send", style = TextStyle( fontSize = 18.sp, color = white, ) ) }
3. 修改ScreenB的入参定义
给ScreenB函数新增手机号参数,直接接收A页面传递的值即可:
@Composable fun ScreenB( navController: NavController, phoneNumber: String // 新增参数,就是ScreenA传入的手机号 ) { lateinit var resendToken: PhoneAuthProvider.ForceResendingToken val focusManager = LocalFocusManager.current // 注意:你原有代码这里状态变量名和下面输入框用的变量名不一致,会编译报错,记得统一 val phoneNumberOTP = remember { mutableStateOf("") } val context = LocalContext.current LaunchedEffect(Unit) { println("found activity? ${context.findActivity()}") val activity = context.findActivity() ?: return@LaunchedEffect modelAuthentication.setActivity(activity) // 这里就可以直接用phoneNumber发起验证码请求了 } // 其余原有布局、逻辑代码完全不用动,重发验证码等场景直接取phoneNumber变量即可 Column( Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { OutlinedTextField( value = phoneNumberOTP.value, colors = TextFieldDefaults.textFieldColors( backgroundColor = white, focusedIndicatorColor = Grey, unfocusedIndicatorColor = Grey, focusedLabelColor = Grey, unfocusedLabelColor = Grey, cursorColor = color, textColor = color, ), onValueChange = { phoneNumberOTP.value = it }, label = { Text(text = "Verify code") }, placeholder = { Text(text = "Verify code") }, modifier = Modifier.fillMaxWidth(0.8f), ) Spacer(modifier = Modifier.padding(7.dp)) Row( Modifier.width(300.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { Text( "Resend Code", modifier = Modifier .height(20.dp) .clickable { // 重发逻辑里直接用phoneNumber即可 }, textAlign = TextAlign.End, fontWeight = FontWeight.Medium, fontSize = 14.sp, color = color ) } } }
补充说明
如果后续要传递带+、/、#等特殊字符的内容,跳转时对参数做一次URL编码即可,写法如下,接收端Navigation会自动解码,不需要额外处理:
val encodePhone = URLEncoder.encode(phoneNumberState.value, "UTF-8") navController.navigate("screenB/$encodePhone")
内容的提问来源于stack exchange,提问作者Huma33
相关产品推荐
相关产品推荐

