如何获取Jetpack Compose Pager的预加载页面索引?
实现懒加载的月份日历Pager方案
核心思路
利用HorizontalPager的offscreenLimit预加载机制,配合缓存管理,仅加载当前页面及前后指定数量页面的月份数据,同时自动清理超出范围的缓存,避免一次性加载所有36个月的数据。
具体实现步骤
1. 配置Pager状态与缓存
定义缓存存储已加载的月份数据,设置预加载页面数量:
// 缓存已加载的月份数据,key为页面索引(对应第n个月份) val calendarDataCache = remember { mutableStateMapOf<Int, List<CalendarDayData>>() } // 设置预加载范围:前后各2页,加上当前共5页,可根据需求调整 val offscreenLimit = 2 val pagerState = rememberPagerState( pageCount = { 36 }, offscreenLimit = offscreenLimit ) // 标记正在加载的页面,避免重复请求数据库 val loadingPages = remember { mutableSetOf<Int>() }
2. 监听页面变化,自动加载/清理数据
通过LaunchedEffect监听当前页面变化,触发目标范围的数据源加载,并清理超出范围的缓存:
LaunchedEffect(pagerState.currentPage) { // 计算需要保留的页面范围:当前页±offscreenLimit,边界不超出0-35 val startPage = max(0, pagerState.currentPage - offscreenLimit) val endPage = min(35, pagerState.currentPage + offscreenLimit) // 加载范围内未缓存且未在加载的页面数据 for (page in startPage..endPage) { if (!calendarDataCache.containsKey(page) && !loadingPages.contains(page)) { loadingPages.add(page) try { // 替换为你的数据库查询逻辑(需为挂起函数) val monthData = queryCalendarDataForMonth(page) calendarDataCache[page] = monthData } finally { loadingPages.remove(page) } } } // 清理超出范围的缓存,释放内存 val pagesToKeep = (startPage..endPage).toSet() calendarDataCache.keys.retainAll(pagesToKeep) }
3. 渲染Pager页面
在每个Pager页面中,从缓存取数据,未加载时显示占位符:
HorizontalPager( state = pagerState, modifier = Modifier.fillMaxWidth(), offscreenLimit = offscreenLimit ) { page -> Column(modifier = Modifier.fillMaxSize()) { calendarDataCache[page]?.let { daysData -> LazyVerticalGrid( columns = GridCells.Fixed(7), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp) ) { items( items = daysData, key = { item: CalendarDayData -> item.dayNumber } ) { day -> CalendarDay( modifier = Modifier.background(Color.Red), calendarDayData = day ) } } } ?: run { // 数据加载中显示的占位符 Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { CircularProgressIndicator() } } } }
关键说明
- offscreenLimit:控制Pager提前加载的前后页面数量,设置为2意味着当前页的前2页和后2页会被提前加载,用户滚动时无需等待数据查询。
- 缓存管理:通过
mutableStateMapOf实时更新缓存,配合页面范围清理,确保内存中仅保留必要的月份数据。 - 防重复请求:用
loadingPages标记正在加载的页面,避免同一页面多次触发数据库查询。
内容的提问来源于stack exchange,提问作者Andreas1234
相关产品推荐
相关产品推荐

