Jetpack Compose配置变更时如何保存PagerState状态?
解决Jetpack Compose配置变更时保存PagerState的问题
核心方案是通过ViewModel持久化当前页码,同时在Composable中完成PagerState与ViewModel状态的双向同步,具体实现如下:
1. 调整ViewModel逻辑
在ViewModel中维护一个可观察的页码状态,用于在配置变更时保留数据:
class TrackScreenManagerViewModel : ViewModel() { // 用MutableStateFlow保存当前页码,初始值设为默认页面(比如1) private val _pagerStateValue = MutableStateFlow(1) val pagerStateValue = _pagerStateValue.asStateFlow() // 提供更新页码的方法 fun updatePagerPage(page: Int) { _pagerStateValue.value = page } }
2. 修改Composable代码
在Composable中,初始化PagerState时使用ViewModel的保存值,同时监听PagerState的页面变化,同步回ViewModel:
@OptIn(ExperimentalFoundationApi::class) @Composable fun TrackScreenManager(navHostController: NavHostController) { val viewModel = koinViewModel<TrackScreenManagerViewModel>() val pagerValue = viewModel.pagerStateValue.collectAsState() // 用ViewModel保存的页码初始化PagerState val pagerState = rememberPagerState(initialPage = pagerValue.value) { 3 } // 监听PagerState的页面变化,同步到ViewModel LaunchedEffect(pagerState) { snapshotFlow { pagerState.currentPage } .distinctUntilChanged() .collect { page -> viewModel.updatePagerPage(page) } } Column(modifier = Modifier.fillMaxSize()) { HorizontalPager( state = pagerState, modifier = Modifier.weight(1f) ) { page -> when (page) { 0 -> SettingsTrackScreen(navHostController) 1 -> MainTrackScreen() 2 -> StatisticsTrackScreen() } } } }
关键说明
- ViewModel持久化:ViewModel在配置变更时不会被销毁,因此
_pagerStateValue能始终保留最新的页码。 - 双向同步:通过
LaunchedEffect监听pagerState.currentPage的变化,确保用户滑动页面后,ViewModel能及时更新状态;配置变更后,rememberPagerState又会用ViewModel保存的页码重新初始化,恢复之前的页面位置。 - 避免重复更新:使用
snapshotFlow配合distinctUntilChanged(),只有当页码真正变化时才同步到ViewModel,减少不必要的状态更新。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

