如何从NavHost向ViewModel传递参数?SavedStateHandle方案失效求助
尝试通过SavedStateHandle从NavHost向NewsScreenViewModel传递参数,但ViewModel无法获取到参数值,调试时NavHost中的source变量已有值。
NewsScreenViewModel代码
@HiltViewModel class NewsScreenViewModel @Inject constructor( val savedStateHandle: SavedStateHandle, ) : ViewModel() { private val _sourceStatus = MutableStateFlow(savedStateHandle.get("source") ?: null) val getSourceStatus: StateFlow<String> get() = _sourceStatus private val _internetStatus = MutableStateFlow(ConnectivityObserver.Status.UNAVAILABLE) val internetStatus: StateFlow<ConnectivityObserver.Status> get() = _internetStatus private val _sourceStatus = MutableStateFlow(savedStateHandle.get("source") ?: FeedSource.NEXTWEB.sourceString ) val getSourceStatus: StateFlow<String> get() = _sourceStatus }
NavHost代码
NavHost(navController = navController, startDestination = Screens.NewsScreen.route) { composable( route = "news/{source}", arguments = listOf( navArgument("source") { type = NavType.StringType defaultValue = "" } ) ) { backStackEntry -> val source = backStackEntry.arguments?.getString("source") ?: "nullsource" NewsScreen(viewModel = newsScreenViewModel, navController = navController, paddingValues = paddingValues) } }
底部导航栏代码
@Composable fun BottomNavigationSection(navController: NavHostController, items: List<Screens>) { BottomNavigation { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route items.forEach { screen -> BottomNavigationItem( modifier = Modifier.background(colorResource(id = R.color.grey)) .fillMaxSize() , icon = { Icon( painterResource(id = screen.icon), contentDescription = screen.route, ) }, selected = currentRoute == screen.route, onClick = { if (currentRoute != screen.route) { navController.navigate(screen.route) } } ) } } }
问题排查与解决步骤
修复ViewModel重复变量定义
代码中重复定义了_sourceStatus和getSourceStatus,这会导致编译错误,同时干扰参数读取逻辑。保留其中一组定义即可,示例:private val _sourceStatus = MutableStateFlow(savedStateHandle.get("source") ?: FeedSource.NEXTWEB.sourceString ) val getSourceStatus: StateFlow<String> get() = _sourceStatus绑定ViewModel与当前BackStackEntry
使用Hilt的hiltViewModel()函数并传入当前backStackEntry,让ViewModel正确关联导航参数。修改NavHost中的ViewModel获取逻辑:val viewModel: NewsScreenViewModel = hiltViewModel(backStackEntry) NewsScreen(viewModel = viewModel, navController = navController, paddingValues = paddingValues)修正底部导航的参数跳转逻辑
底部导航跳转时需要携带完整的带参数路由,不能直接使用screen.route(如果它是不含参数的模板)。示例调整:// 假设Screens类中每个页面有对应的source参数值 navController.navigate("news/${screen.sourceParam}")添加日志验证参数读取
在ViewModel的init块中添加日志,确认SavedStateHandle是否正确获取参数:init { Log.d("NewsVM", "SavedStateHandle source: ${savedStateHandle.get<String>("source")}") }
内容的提问来源于stack exchange,提问作者Alex20280
相关产品推荐
相关产品推荐

