首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安卓寻呼3 remoteMediator无限加载(附加)数据与合成

安卓寻呼3 remoteMediator无限加载(附加)数据与合成
EN

Stack Overflow用户
提问于 2022-07-20 06:40:57
回答 1查看 853关注 0票数 0

我正在尝试使用RemoteMediator实现一个带有分页3库的列表。

初始加载是可以的。中介只加载了3页,设置在“PageConfig”中。在我的例子中,每页有10个数据。

但是,当滚动列表以触发更多数据的额外加载时,Mediator将无限地开始加载数据,直到它返回MediatorResult.Success(endOfPaginationReached = true) (这意味着远程中的所有数据都已加载)。即使滚动停止了。

我不知道是什么让中介继续加载。

我希望Mediator在滚动过程中加载只需要的数据。

这是我的代码:

代码语言:javascript
运行
复制
@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)
        }
    }
}
代码语言:javascript
运行
复制
@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
    }
}
代码语言:javascript
运行
复制
@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代码:

代码语言:javascript
运行
复制
@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() } }
                }
            }
        }
    }
}

谢谢你的回答

EN

回答 1

Stack Overflow用户

发布于 2022-08-31 21:33:20

在创建pageSize时增加PageConfig。

根据文件:

应该是屏幕上可见项数的几倍。配置页面大小取决于如何加载和使用数据。较小的页面大小改善了内存的使用、延迟和避免GC的搅动。更大的页面通常会在一定程度上提高加载吞吐量(避免一次从SQLite加载超过2MB的数据,因为这会带来额外的成本)。如果您正在为占用大部分屏幕的非常大的社交媒体样式卡加载数据,而且您的数据库不是瓶颈,那么10-20可能是有意义的。如果您要在平铺网格中显示数十个项目,这样可以更快地在滚动过程中显示项目,请考虑更接近100。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73047015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档