屏幕导航时如何让Screen2获取ViewModel中已更新的值?
问题分析
你遇到的核心问题是:hiltViewModel()默认会为每个导航目标(Destination)创建独立的ViewModel实例,因此Screen2获取到的是全新的VM对象,自然无法看到Screen1修改后的appState值。
解决方案
要让两个Screen共享同一个ViewModel实例,只需让它们从同一个ViewModelStoreOwner中获取ViewModel即可,最常用的方式是使用导航控制器的ViewModelStoreOwner:
修改后的代码
ViewModel 保持不变
@HiltViewModel class VM @Inject constructor(): ViewModel() { var appState: Boolean by mutableStateOf(false) }
Screen1 修改获取ViewModel的方式
@Destination @Composable fun ScreenOne(nav: DestinationsNavigator, vm: VM = hiltViewModel(nav.navController.viewModelStoreOwner)){ vm.appState.value = true nav.navigate(ScreenTwoDestination()) }
Screen2 修改获取ViewModel的方式
@Destination @Composable fun ScreenTwo(nav: DestinationsNavigator, vm: VM = hiltViewModel(nav.navController.viewModelStoreOwner)){ Log.i("ScreenTwo", vm.appState.toString()) // 现在会输出true }
原理说明
nav.navController.viewModelStoreOwner对应的是整个导航组件的ViewModel存储容器,其生命周期与导航控制器一致。两个Screen从这里获取ViewModel时,会拿到同一个实例,因此Screen1对appState的修改会同步到Screen2中。
注意:确保你的宿主Activity已经添加了
@AndroidEntryPoint注解,Hilt才能正常注入ViewModel。
内容的提问来源于stack exchange,提问作者Beqa Huelu
相关产品推荐
相关产品推荐

