如何在Navigation Compose中正确传递出生日期参数?
问题解决:Jetpack Compose导航传递出生日期崩溃的修复
崩溃核心原因
- 错误传递MutableState对象:跳转时使用
$date,但date是MutableState<String>类型,直接拼接会将对象的内存地址字符串传入路由,导致路由格式完全失效。 - 特殊字符未编码:日期格式中的
/属于URL保留字符,直接放入路由参数会破坏导航路由结构,引发解析异常。
修复步骤
1. 导入编码解码工具类
在代码文件顶部添加:
import java.net.URLEncoder import java.net.URLDecoder
2. 修正跳转逻辑:传递实际日期值并编码
在FirstPage的跳转按钮点击事件中,替换为以下代码:
Button(onClick = { // 对日期字符串进行URL编码,处理特殊字符 val encodedDate = URLEncoder.encode(date.value, "UTF-8") // 传递date.value而非date对象 navController.navigate("secondPage/$nameR/$familyR/$idR/$encodedDate") }) { Text(text = "first page btn") }
3. 修正接收逻辑:解码日期参数
在NavGraph的secondPage节点中,对接收的日期参数进行解码:
composable("secondPage/{name}/{lastName}/{id}/{date}") { backStackEntry -> val encodedDate = backStackEntry.arguments?.getString("date") ?: "" // 解码还原日期字符串 val decodedDate = URLDecoder.decode(encodedDate, "UTF-8") SecondPage( navController = navController, name = backStackEntry.arguments?.getString("name") ?: "", lastName = backStackEntry.arguments?.getString("lastName") ?: "", id= backStackEntry.arguments?.getString("id") ?: "", date= decodedDate ) }
额外优化:修复日期显示的月份偏移
当前datepicker中月份是从0开始计数(Calendar.MONTH返回0代表1月),导致选择1月时显示为0,建议修改datepicker的赋值逻辑:
date.value="$dayOfMonth/${month+1}/$year"
完整修正后代码
NavGraph
import java.net.URLDecoder import androidx.compose.runtime.Composable import androidx.navigation.NavController import androidx.navigation.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @Composable fun NavGraph() { val navController = rememberNavController() NavHost(navController = navController, startDestination = "firstPage") { composable("firstPage") { FirstPage(navController = navController) } composable("secondPage/{name}/{lastName}/{id}/{date}") { backStackEntry -> val encodedDate = backStackEntry.arguments?.getString("date") ?: "" val decodedDate = URLDecoder.decode(encodedDate, "UTF-8") SecondPage( navController = navController, name = backStackEntry.arguments?.getString("name") ?: "", lastName = backStackEntry.arguments?.getString("lastName") ?: "", id= backStackEntry.arguments?.getString("id") ?: "", date= decodedDate ) } } }
FirstPage(仅展示修改部分)
import java.net.URLEncoder // ... 其他原有导入 @Composable fun FirstPage(navController: NavController) { // ... 原有变量定义 // ... 原有UI代码 Button(onClick = { val encodedDate = URLEncoder.encode(date.value, "UTF-8") navController.navigate("secondPage/$nameR/$familyR/$idR/$encodedDate") }) { Text(text = "first page btn") } }
datepicker(优化月份显示)
@Composable fun datepicker(context: Context , date: MutableState<String> ){ val calender = Calendar.getInstance() val year=calender.get(Calendar.YEAR) val month=calender.get(Calendar.MONTH) val day=calender.get(Calendar.DAY_OF_MONTH) val datePickerDialog= DatePickerDialog( context,{ _: DatePicker, year:Int, month:Int, dayOfMonth:Int -> // 月份+1修正偏移 date.value="$dayOfMonth/${month+1}/$year" },year,month,day ) Row { Button( onClick = { datePickerDialog.show() } ) { Text(text = "Select your birthday ") } Text(text = "${date.value}", fontSize = 15.sp, textAlign = TextAlign.End) } }
内容的提问来源于stack exchange,提问作者Nastaran Ebrahimi
相关产品推荐
相关产品推荐

