Navigation Component自动向SavedStateHandle存储参数机制问询
是的,Navigation组件会自动将导航参数以你定义的键名存入对应ViewModel的SavedStateHandle中,无需手动传递或设置参数。
机制原理与细节
导航参数的绑定逻辑
当你在Composable中使用hiltViewModel()(或官方的viewModel())获取ViewModel时,Navigation组件会自动关联当前导航目的地的参数集合,并将这些参数注入到ViewModel的SavedStateHandle实例中。具体实现流程
- 在NavGraph中定义带参数的
composable时,你通过navArgument指定的参数名称(比如示例中的"movieId")会被Navigation组件记录为参数键。 - 当导航到该目的地时,Navigation会解析路由中的参数值,将其存入当前目的地的
SavedState容器中。 - 创建ViewModel时,Navigation结合依赖注入框架(比如Hilt)会自动把该目的地的
SavedState包装成SavedStateHandle,并通过构造函数注入到ViewModel里。 - 最终你就能直接通过参数键名从
SavedStateHandle中取出对应的值,无需额外代码。
补充注意事项
- 若使用Hilt,ViewModel必须添加
@HiltViewModel注解,否则无法完成自动注入(示例代码中建议补充该注解)。 - 参数键名必须与
navArgument中定义的完全匹配,否则SavedStateHandle中无法找到对应值。 - 若参数设置为可选(比如未指定
nullable = false),SavedStateHandle中对应的键值会是null,需要做好空值判断。 - 路由定义时,参数占位符必须用大括号包裹(如
"detail_route/{movieId}"),否则Navigation无法正确解析路由中的参数值。
修正后的代码示例
// NavGraph composable composable( route = "detail_route/{movieId}", arguments = listOf( navArgument("movieId") { type = NavType.IntType } ) ) { val viewModel = hiltViewModel<DetailViewModel>() DetailScreen( viewModel = viewModel ) } // DetailViewModel @HiltViewModel class DetailViewModel( savedStateHandle: SavedStateHandle ) : ViewModel() { private val movieId: Int? = savedStateHandle["movieId"] fun getMovieInformation() { val movieData: Movie = repository.getSelectedMovieData(movieId) } }
内容的提问来源于stack exchange,提问作者Android Developer
相关产品推荐
相关产品推荐

