如何通过DeepLink从通知导航至Composable页面并传递idNotation参数
解决方法
1. 修正路由定义与生成方法
你当前的Screen路由只包含id参数,需要把idNotation加入并设为可选参数,这样能同时兼容列表点击传id、通知点击传idNotation的场景。修改后的代码如下:
object Screen : AppDestination("screen/{id}?idNotation={idNotation}") { // 列表点击调用:id必填,idNotation可选 fun createRoute(id: String, idNotation: String? = null): String { return buildString { append("screen/$id") idNotation?.let { append("?idNotation=$it") } } } // 通知跳转专用:无需id,直接传idNotation fun createRouteFromNotification(idNotation: String): String { return "screen/default?idNotation=$idNotation" } }
如果你的Screen页面允许id为空,也可以把路由改成screen?id={id}&idNotation={idNotation},后续在参数配置里标记nullable = true即可。
2. 同步更新导航图配置
原来的screenGraph中路由与参数配置不匹配,需要同步调整,同时要把idNotation传递给目标页面:
fun NavGraphBuilder.screenGraph( navController: NavHostController ) { composable( route = Screen.route, arguments = listOf( navArgument("id") { type = NavType.StringType defaultValue = "default" // 设置默认值避免参数缺失崩溃 }, navArgument("idNotation") { type = NavType.StringType nullable = true // 标记为可选参数 defaultValue = null } ), deepLinks = listOf( navDeepLink { // 匹配带id/idNotation的Uri,兼容单参数场景 uriPattern = "myapp://screennavigation?id={id}&idNotation={idNotation}" // 若通知跳转无需id,可单独添加规则: // uriPattern = "myapp://screennavigation/idNotation={idNotation}" } ) ) { backStackEntry -> Screen( payloadId = backStackEntry.arguments?.getString("id"), idNotation = backStackEntry.arguments?.getString("idNotation") // 传递idNotation参数 ) } }
3. 构建通知跳转的Pending Intent
你已经能获取到idNotation,现在把它传入Pending Intent即可,两种实现方式任选:
// 方式一:通过DeepLink Uri传递参数 val deepLinkUri = Uri.parse("myapp://screennavigation?id=default&idNotation=$yourIdNotationValue") val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) // 你的导航图资源ID .setDestination(R.id.screen) // 目标Screen的ID .setUri(deepLinkUri) .createPendingIntent() // 方式二:直接通过Bundle传递参数 val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.screen) .setArguments(bundleOf( "id" to "default", // 允许id为空的话可传null "idNotation" to yourIdNotationValue )) .createPendingIntent()
4. 更新Screen页面接收参数
最后给你的Screen Composable添加idNotation参数,就能在页面内使用该值:
@Composable fun Screen( payloadId: String?, idNotation: String? // 新增参数接收idNotation ) { // 这里即可基于idNotation实现业务逻辑 }
关键注意点
- 可选参数必须在路由中用
?标记,同时在navArgument中设置默认值或允许为空,避免参数缺失导致崩溃。 - DeepLink的Uri格式要与配置的
uriPattern完全匹配,否则Navigation无法解析参数。 - 两种跳转场景分开调用:列表点击用
Screen.createRoute(id = "xxx"),通知跳转用Screen.createRouteFromNotification(idNotation = "xxx")。
内容的提问来源于stack exchange,提问作者Saul
相关产品推荐
相关产品推荐

