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

如何获取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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 23:04:59