Jetpack Compose页面传参异常:surveyToken传递至ResultScreen报错
问题场景
需要将surveyToken传递到ResultScreen,但运行时抛出找不到导航目的地的错误,相关代码及报错如下:
跳转调用代码
surveyScreen( moveToResult = { surveyToken -> navController.navigateToResult(surveyToken) } )
navigateToResult函数及导航图配置
const val resultRoute = "result_route" fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) { this.navigate("$resultRoute/$SURVEY_TOKEN?=$surveyToken", navOptions) } @OptIn(ExperimentalAnimationApi::class) fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) { composable(route = resultRoute) { ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity)) } }
ResultViewModel代码
@HiltViewModel class ResultViewModel @Inject constructor( savedStateHandle: SavedStateHandle, val snackBarMonitor: SnackBarMonitor ) : ViewModel() { private val surveyToken: String = checkNotNull(savedStateHandle[SURVEY_TOKEN]) }
报错信息
java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/result_route/survey_token?=711d28d33d0fd880459108da5aeb819fce94948f49bdbed20117a27c7109 } cannot be found in the navigation graph NavGraph(0x0) startDestination={NavGraph(0x22fb6594) route=entry_graph startDestination={Destination(0x2395568f) route=entry_route}}
错误原因
- 导航路由定义不匹配:
resultScreen的composable路由仅定义了result_route,未包含参数占位符,但跳转时使用了带参数的路径,导致Navigation无法匹配到对应的目的地。 - 传参格式错误:
navigateToResult中拼接的路径格式错误,$resultRoute/$SURVEY_TOKEN?=$surveyToken既不是标准的路径参数格式,也不是查询参数格式,导致生成的URI无法被识别。
解决方案
方案1:使用查询参数传递(推荐)
步骤1:修正导航路由定义
在resultScreen的composable中添加查询参数占位符:
@OptIn(ExperimentalAnimationApi::class) fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) { // ?后表示参数可选,若需必填可去掉? composable(route = "$resultRoute?$SURVEY_TOKEN={$SURVEY_TOKEN}") { ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity)) } }
步骤2:修正navigateToResult函数的路径拼接
使用标准查询参数格式拼接路径:
fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) { this.navigate("$resultRoute?$SURVEY_TOKEN=$surveyToken", navOptions) }
方案2:使用路径参数传递
步骤1:修正导航路由定义
将参数作为路径一部分,添加路径参数占位符:
@OptIn(ExperimentalAnimationApi::class) fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) { composable(route = "$resultRoute/{$SURVEY_TOKEN}") { ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity)) } }
步骤2:修正navigateToResult函数的路径拼接
直接将参数拼接到路径中:
fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) { this.navigate("$resultRoute/$surveyToken", navOptions) }
验证参数获取
两种方案中,ResultViewModel通过SavedStateHandle获取参数的代码无需修改,Navigation会自动将路径/查询参数注入到SavedStateHandle中,只需确保SURVEY_TOKEN常量名称和路由中使用的一致即可。
内容的提问来源于stack exchange,提问作者c-an
相关产品推荐
相关产品推荐

