Navigation3中如何用SavedStateHandle传参?迁移后遇空指针问题
一、类型安全的参数传递(推荐使用 Safe Args)
这是Navigation官方推荐的方式,能避免参数名拼写错误和类型不匹配问题,步骤如下:
- 在导航图中定义参数
在nav_graph.xml里,给Report页面对应的<destination>节点添加<argument>配置,指定参数名、类型和默认值(避免空指针):
<fragment android:id="@+id/reportFragment" android:name="com.yourpackage.ReportFragment"> <argument android:name="id" app:argType="long" <!-- 根据实际参数类型调整,如int/string --> android:defaultValue="-1"/> <!-- 设置默认值,防止未传参时触发空指针 --> </fragment>
- 生成Safe Args代码并执行跳转
Android Studio会自动生成对应的方向类(确保项目已添加Safe Args依赖),在Calendar页面跳转时通过生成的类传递参数:
// Calendar页面的跳转代码 findNavController().navigate(CalendarFragmentDirections.actionCalendarToReport(id = targetId))
二、通过SavedStateHandle接收参数
ViewModel中获取参数时,要保证参数名和导航图定义的完全一致,同时用默认值兜底避免空指针:
class ReportViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { // 直接获取参数,用默认值兜底 val reportId: Long = savedStateHandle.get<Long>("id") ?: -1 // 若参数可能动态更新,可使用LiveData监听 val reportIdLiveData = savedStateHandle.getLiveData<Long>("id", -1) }
三、不使用Safe Args的Bundle传递方式(不推荐)
如果暂时不想用Safe Args,也可以直接用Bundle传递,但要严格保证参数名和类型一致:
// Calendar页面跳转代码 val bundle = Bundle().apply { putLong("id", targetId) } findNavController().navigate(R.id.action_calendar_to_report, bundle)
接收参数的方式和上述SavedStateHandle的写法一致。
关键注意事项
- 参数名大小写敏感,导航图定义的名称必须和代码中使用的完全匹配
- 必须给参数设置默认值,即使你确保一定会传参,也能避免意外情况导致的空指针
- 检查NavDisplay的导航配置,确保跳转的action正确指向Report页面,没有遗漏参数传递
- 若使用依赖注入框架(如Hilt),要保证ViewModel的SavedStateHandle被正确注入,禁止手动实例化ViewModel
内容的提问来源于stack exchange,提问作者Nontas Papadopoulos
相关产品推荐
相关产品推荐

