Android:使用RemoteMediator分页时未滚动前持续触发PREPEND加载
问题:RemoteMediator未滚动时持续触发PREPEND加载
尝试使用RemoteMediator实现分页功能,远程数据源为随机狗图API,该接口不支持分页,每次请求返回一组随机狗图URL列表。应用启动后执行初始刷新,但不进行滚动操作时,RemoteMediator会持续以LoadType.PREPEND类型加载数据;一旦开始滚动,该现象停止,且向下滑动时会正常触发LoadType.APPEND加载更多数据。
现有RemoteMediator代码
class DogImageRemoteMediator( private val database: DogImageDatabase, private val networkService: DogImageApiService ) : RemoteMediator<Int, DogImageEntity>() { val dogImageDao = database.dogImageDao() override suspend fun load( loadType: LoadType, state: PagingState<Int, DogImageEntity> ): MediatorResult { return try { val response = networkService.getDogImages(DogImageApiService.BATCH_SIZE) database.withTransaction { if (loadType == LoadType.REFRESH) { dogImageDao.clearAll() } dogImageDao.insertAll(response.imageUrls.map { url -> DogImageEntity(url = url) }) MediatorResult.Success(endOfPaginationReached = false) } } catch (e: IOException) { MediatorResult.Error(e) } catch (e: HttpException) { MediatorResult.Error(e) } } override suspend fun initialize(): InitializeAction { return InitializeAction.LAUNCH_INITIAL_REFRESH } }
触发日志
// ... PREPEND // 未滚动时重复触发 Anchor position: null Clipped refresh key: null PREPEND // 此处已滚动 Anchor position: 31 Clipped refresh key: 26
当前PagingConfig配置
PagingConfig(pageSize = 30, initialSize = 10, prefetchDistance = 10)
解决方案
1. 直接忽略PREPEND请求(核心修复)
由于你的API不支持分页,没有"上一页"的概念,PREPEND加载完全没有意义。在load方法开头增加判断,直接返回Success(endOfPaginationReached = true),告诉Paging不需要再加载前面的数据:
override suspend fun load( loadType: LoadType, state: PagingState<Int, DogImageEntity> ): MediatorResult { // 忽略PREPEND请求,API无向前分页能力 if (loadType == LoadType.PREPEND) { return MediatorResult.Success(endOfPaginationReached = true) } return try { val response = networkService.getDogImages(DogImageApiService.BATCH_SIZE) database.withTransaction { if (loadType == LoadType.REFRESH) { dogImageDao.clearAll() } dogImageDao.insertAll(response.imageUrls.map { url -> DogImageEntity(url = url) }) MediatorResult.Success(endOfPaginationReached = false) } } catch (e: IOException) { MediatorResult.Error(e) } catch (e: HttpException) { MediatorResult.Error(e) } }
2. 调整PagingConfig参数(可选优化)
将initialSize设置为与pageSize一致,避免初始加载数据量过小,导致Paging认为列表起始位置需要补充数据:
PagingConfig(pageSize = 30, initialSize = 30, prefetchDistance = 10)
原因说明
未滚动时锚点位置为null,Paging库检测到当前列表顶部的数据量未满足prefetchDistance的要求,会不断触发PREPEND尝试补充数据。而你的API本身不支持向前分页,所以直接忽略PREPEND请求即可解决无限触发的问题。
内容的提问来源于stack exchange,提问作者woxiangqiu
相关产品推荐
相关产品推荐

