如何在AndroidX Navigation路由中设置可选的Int类型导航参数
我太懂你碰到的这个痛点了——用AndroidX Navigation做App路由时,想把Int类型的参数设为可选项,但踩了好几个坑:要么不给默认值直接崩,要么试着把参数设为可空又报错,还没法用Safe Args简化操作。
先理下你的场景:Catalog页面的路由支持带完整参数的形式(比如myapp://catalog?section=books&itemId=69),也希望能直接跳转到不带itemId的myapp://catalog?section=books。但定义导航参数时,遇到了两个棘手的问题:
问题1:不设默认值会触发运行时错误
如果不给itemId设置默认值,当你通过不带该参数的深度链接跳转时,会直接抛出类似这样的异常:
java.lang.IllegalArgumentException: Deep link myapp://catalog?section=Books can't be used to open destination Destination(0x0). Following required arguments are missing: [itemId]
这是因为Navigation会把没有默认值的参数判定为必填项,深度链接里缺失的话就会直接报错。
问题2:Int类型参数不能设为可空
你可能试过把itemId设为可空参数,比如这样写:
navArgument(PlantSheetDestination.itemId) { type = NavType.IntType nullable = true }
但会立刻触发这个错误:
java.lang.IllegalArgumentException: integer does not allow nullable value
这是因为NavType.IntType本身不支持可空类型,官方也明确了这一点——Int类型的导航参数没办法设为可空。
目前可行的解决方案:用特殊默认值模拟可选参数
现在最稳妥的办法,就是给itemId设置一个业务上不会用到的特殊默认值(比如-1或者Int.MIN_VALUE),以此来标记“参数未传递”的状态。就像你现在写的这样:
composable( route = CatalogDestination.routeWithArgs, arguments = listOf( navArgument(CatalogDestination.sectionArg) { type = NavType.StringType defaultValue = "Books" }, navArgument(PlantSheetDestination.itemId) { type = NavType.IntType defaultValue = -1 } ), )
之后在Catalog页面的逻辑里,只要判断itemId是否等于这个默认值,就能区分出用户是带参数跳转还是不带参数跳转:
val itemId = navBackStackEntry.arguments?.getInt(PlantSheetDestination.itemId) ?: -1 if (itemId != -1) { // 处理带itemId的业务逻辑 } else { // 处理不带itemId的业务逻辑 }
如果你的业务里-1是合理的有效值,那建议换一个更特殊的默认值(比如Int.MIN_VALUE),避免和正常业务逻辑冲突。
备注:内容来源于stack exchange,提问作者Akronix
相关产品推荐
相关产品推荐

