使用observeAsState观察LiveData时屏幕旋转状态不保留,当前rememberSaveable用法是否正确?
你的写法存在两个关键问题,不完全正确
首先来说说当前实现的问题:
- rememberSaveable的key参数使用错误:你把
accountsState.value作为rememberSaveable的key,而这个值会随着LiveData的更新而变化。每次key改变,rememberSaveable都会认为这是一个全新的状态容器,会重新初始化accountsList,导致之前保存的旋转状态直接失效。 - 没有同步LiveData的更新:你只在初始化时把
accountsState.value赋值给accountsList,但当ViewModel的userAccountsLiveData数据更新时,accountsList不会自动跟着变化,这会导致UI显示的数据和LiveData不同步。
正确的解决思路
其实优先推荐的方案是确保ViewModel的正确创建,因为ViewModel本身就是为了在屏幕旋转等配置变更时保留数据而设计的:
在Compose中,你应该使用viewModel()函数来获取ViewModel实例(比如val viewModel: YourViewModel = viewModel()),这样旋转屏幕时ViewModel不会被销毁,它持有的userAccounts LiveData会保留之前的数据,observeAsState会自动观察到这些数据,不需要额外的rememberSaveable就能保留状态。
如果因为某些场景确实需要用rememberSaveable来本地保存状态,那可以这样修改:
val accountsState: State<List<UserProfile>> = viewModel.userAccounts.observeAsState(initial = emptyList()) // 这里不要把accountsState.value作为key,让rememberSaveable使用默认的key(基于变量名生成) var accountsList by rememberSaveable { mutableStateOf(accountsState.value) } // 监听accountsState的变化,同步更新accountsList LaunchedEffect(accountsState.value) { accountsList = accountsState.value }
这样做的好处:
rememberSaveable的key稳定,旋转时能正确恢复之前保存的accountsList- 当LiveData的数据更新时,
LaunchedEffect会触发,自动把新数据同步到accountsList,保证UI数据和LiveData一致
另外要注意:UserProfile类必须是可序列化的(比如实现Serializable接口,或者用Parcelize注解),否则rememberSaveable无法保存它的实例。
内容的提问来源于stack exchange,提问作者Android Newcomer
相关产品推荐
相关产品推荐

