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

如何在Navigation Compose中正确传递出生日期参数?

问题解决:Jetpack Compose导航传递出生日期崩溃的修复

崩溃核心原因

  1. 错误传递MutableState对象:跳转时使用$date,但date是MutableState<String>类型,直接拼接会将对象的内存地址字符串传入路由,导致路由格式完全失效。
  2. 特殊字符未编码:日期格式中的/属于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:47:03