我试图实现一个列表与分页3库使用RemoteMediator。
初始加载正常。Mediator仅加载了3个页面,这是在“PageConfig”中设置的。在我的例子中,每页有10个数据。
但是,当滚动列表以触发更多数据的额外加载时,Mediator将开始无限加载数据,直到返回MediatorResult.Success(endOfPaginationReached = true)
(这意味着远程中的所有数据都已加载)。即使滚动停止。
我不知道是什么让Mediator继续加载。
我希望中介加载数据只需要沿沿着。
下面是我的代码:
@OptIn(ExperimentalPagingApi::class)
class PostRemoteMediator(
private val postApi: ApiInterface,
private val database: PostDatabase
) : RemoteMediator<Int, Post>() {
override suspend fun load(loadType: LoadType, state: PagingState<Int, Post>): MediatorResult {
return try {
val userId = when (loadType) {
LoadType.REFRESH -> {
logd(">> loadType.REFRESH")
STARTING_USER_ID
}
LoadType.PREPEND -> {
return MediatorResult.Success(endOfPaginationReached = true)
}
LoadType.APPEND -> {
logd(">> loadType.APPEND")
val lastItem = state.lastItemOrNull()
?: return MediatorResult.Success(endOfPaginationReached = true)
lastItem.userId + 1
}
}
logd(">> load data with userId = $userId")
val response = postApi.getUserPosts(userId)
database.withTransaction {
if (loadType == LoadType.REFRESH) {
database.postsDao().clearAll()
}
database.postsDao().insertAll(response?.body() ?: emptyList())
}
MediatorResult.Success(
endOfPaginationReached = response.body().isNullOrEmpty()
)
} catch (e: IOException) {
MediatorResult.Error(e)
} catch (e: HttpException) {
MediatorResult.Error(e)
}
}
}
@OptIn(ExperimentalPagingApi::class)
class PostRepositoryImpl @Inject constructor(
private val remoteApi: ApiInterface,
private val database: PostDatabase
) : PostRepository {
override fun getUserPosts(): Flow<PagingData<Post>> {
return Pager(
config = PagingConfig(
pageSize = 1
),
remoteMediator = PostRemoteMediator(
remoteApi,
database
)
) {
// returns all data in table as PagingSource<Int, Post>
database.postsDao().getPosts()
}.flow
}
}
@HiltViewModel
class PostViewModel @Inject constructor(
private val postRepository: PostRepository
) : ViewModel() {
private val TAG = PostViewModel::class.simpleName
val postFlow: Flow<PagingData<Post>> = postRepository.getUserPosts().cachedIn(viewModelScope)
}
这是UI代码:
@Composable
fun PostList(postsFlow: Flow<PagingData<Post>>) {
val posts = postsFlow.collectAsLazyPagingItems()
LazyColumn(contentPadding = PaddingValues(horizontal = 8.dp)) {
items(posts, key = { it.id }) { post ->
post?.also { PostItem(userId = it.userId, id = it.id, content = it.body) }
}
posts.apply {
when {
loadState.mediator?.refresh is LoadState.Loading -> {
item { LoadingView(modifier = Modifier.fillParentMaxSize()) }
}
loadState.mediator?.append is LoadState.Loading -> {
item { LoadingView(modifier = Modifier.wrapContentHeight()) }
}
loadState.mediator?.refresh is LoadState.Error -> {
val error = loadState.refresh as LoadState.Error
item { ErrorView(error.error.localizedMessage!!, modifier = Modifier.fillParentMaxSize()) { retry() } }
}
loadState.mediator?.append is LoadState.Error -> {
val error = loadState.append as LoadState.Error
item { ErrorView(error.error.localizedMessage!!, modifier = Modifier.wrapContentHeight()) { retry() } }
}
}
}
}
}
谢谢你的回答
2条答案
按热度按时间zbdgwd5y1#
在创建PageConfig时增加pageSize。
根据文件:
应该是可见项目数的几倍。配置页面大小取决于加载和使用数据的方式。较小的页面大小可以改善内存使用、延迟,并避免GC扰动。较大的页面通常可以提高加载吞吐量(避免一次从SQLite加载超过2 MB,因为这会产生额外的成本)。如果你加载的数据非常大,社交媒体风格的卡片占据了大部分屏幕,而且你的数据库不是瓶颈,那么10-20可能是有意义的。如果你要在平铺网格中显示几十个项目,这可以在滚动过程中更快地显示项目,考虑接近100个。
3gtaxfhh2#
首先确保initialLoadSize小于在remoteMediator中使用的pageSize,当你将其分配给pageSize时使用larg数字取决于你有多少数据,在我的情况下,我使用15 pagesize,因为我在我的寻呼机中有75个项目,其次使用这种方式在lazy列中显示项目,这对我很有用,