Jetpack Compose跨Composable组件ViewModel变量值无法保持问题
你遇到的核心问题是:两个页面获取的是不同的ContinentsViewModel实例,哪怕在同一Navigation Host中,默认ViewModel的作用域是单个页面目的地(Destination),所以每个页面会独立创建自己的ViewModel实例,导致状态无法共享。
解决方案
1. 将ViewModel作用域绑定到整个导航图
默认的viewModel()方法会把ViewModel绑定到当前页面的BackStackEntry,要实现跨页面共享,需要将ViewModel绑定到整个导航图的BackStackEntry:
在两个页面中,都通过导航图的ID获取对应的BackStackEntry,再以此为作用域获取ViewModel:
// 在DiscoverCountries和ContinentsCountriesPage页面中都用这段代码获取ViewModel val navController = rememberNavController() // 替换成你的导航图ID val navGraphBackStackEntry = remember(navController) { navController.getBackStackEntry(R.id.your_nav_graph_id) } val continentsViewModel = viewModel<ContinentsViewModel>(navGraphBackStackEntry)
2. 若使用Hilt注入ViewModel的适配
如果用Hilt管理ViewModel,需要指定导航图作用域的BackStackEntry来获取实例:
val navGraphBackStackEntry = navController.getBackStackEntry(R.id.your_nav_graph_id) val continentsViewModel = hiltViewModel<ContinentsViewModel>(navGraphBackStackEntry)
不要直接调用无参的hiltViewModel(),否则会绑定当前页面的作用域。
3. 确认Navigation Host的导航图结构
确保两个页面都属于同一个<navigation>定义的导航图中,Navigation Host也使用该导航图作为根:
NavHost(navController = navController, startDestination = "discover_countries") { // 根导航图,包含两个页面 navigation(startDestination = "discover_countries", route = "your_nav_graph_id") { composable("discover_countries") { DiscoverCountries() } composable("continents_countries") { ContinentsCountriesPage() } } }
核心逻辑
ViewModel的作用域决定了实例的生命周期,将作用域从单个页面提升到整个导航图后,所有属于该导航图的页面都会共享同一个ViewModel实例,状态自然就能跨页面保持一致。
内容的提问来源于stack exchange,提问作者jair
相关产品推荐
相关产品推荐

