You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose跨Composable组件ViewModel变量值无法保持问题

解决Jetpack Compose同一Navigation Host下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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:17:03