在 Jetpack Compose 中使用 Paging 3 Remote Mediator 时如何解决无限 API 调用甚至不滚动的问题

问题描述 投票:0回答:1

我是新手,刚刚学习使用 Jetpack Compose。我在我的远程中介器上发现了无限 API 调用的错误。我正在使用底部栏。这是我的代码:

这是我的远程中介类

@OptIn(ExperimentalPagingApi::class)
class TopAnimeRemoteMediator(
    private val apiService: ApiService,
    private val database: TopAnimeDatabase,
) : RemoteMediator<Int, TopAnimeResponse>() {
    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, TopAnimeResponse>
    ): MediatorResult {
        val page = when (loadType) {
            LoadType.REFRESH -> 1
            LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
            LoadType.APPEND -> {
                val lastItem = state.lastItemOrNull()
                Log.d("RRREMOTE", lastItem?.pagination?.currentPage.toString())
                if (lastItem?.pagination?.hasNextPage == false) {
                    return MediatorResult.Success(endOfPaginationReached = true)
                } else {
                    lastItem?.pagination?.currentPage?.plus(1)
                }
            }
        }

        return try {
            val response = apiService.getTopAnime("g", page, PAGE_SIZE_CONFIG)
            database.withTransaction {
                if (loadType == LoadType.REFRESH) {
                    database.topAnimeDao().deleteTopAnime()
                }
                database.topAnimeDao().insertTopAnime(listOf(response))
            }
            MediatorResult.Success(endOfPaginationReached = !response.pagination.hasNextPage)
        } catch (e: Exception) {
            return MediatorResult.Error(e)
        } catch (e: HttpException) {
            MediatorResult.Error(e)
        }
    }

    companion object {
        const val PAGE_SIZE_CONFIG = 5
    }
}

这是我的存储库

class TopAnimeRepository(private val apiService: ApiService, private val topAnimeDatabase: TopAnimeDatabase) {

    @OptIn(ExperimentalPagingApi::class)
    fun getTopAnime(): Flow<PagingData<TopAnimeResponse>> {
        return Pager(
            config = PagingConfig(
                pageSize = TopAnimeRemoteMediator.PAGE_SIZE_CONFIG
            ),
            remoteMediator = TopAnimeRemoteMediator(
                apiService, topAnimeDatabase
            ),
            pagingSourceFactory = {
                topAnimeDatabase.topAnimeDao().getAllTopAnime()
            }
        ).flow
    }
}

这是我的视图模型

class MainViewModel(database: TopAnimeDatabase) : ViewModel() {

    private val apiService: ApiService = ApiConfig.getAnimeApiService()
    private val topAnimeRepository = TopAnimeRepository(apiService, database)

    val topAnimePager: Flow<PagingData<TopAnimeResponse>> =
        topAnimeRepository.getTopAnime().cachedIn(viewModelScope)
}

这里是视图

@Composable
fun HomeScreenBase(modifier: Modifier = Modifier) {

    val context = LocalContext.current
    val mainViewModel: MainViewModel = viewModel {
        MainViewModel(TopAnimeDatabase.getDatabase(context))
    }

    val topAnimeList = mainViewModel.topAnimePager.collectAsLazyPagingItems()
    val snackBarHostState = remember { SnackbarHostState() }
    val errorMessage = stringResource(R.string.failed_to_retrieve_data)

    when (topAnimeList.loadState.refresh) {
        LoadState.Loading -> {
            Box(
                modifier = modifier
                    .fillMaxSize()
                    .padding(bottom = 16.dp), // Adjust the padding as needed
                contentAlignment = Alignment.BottomCenter
            ) {
                CircularProgressIndicator()
            }
        }

        is LoadState.Error -> {
            LaunchedEffect(snackBarHostState) {
                snackBarHostState.showSnackbar(
                    message = errorMessage,
                    duration = SnackbarDuration.Short,
                    withDismissAction = true,
                )
            }
            Scaffold(snackbarHost = { SnackbarHost(hostState = snackBarHostState) }){ paddingValues -> modifier.padding(paddingValues) }
        }

        else -> {
            LazyVerticalStaggeredGrid(
                columns = StaggeredGridCells.Adaptive(200.dp),
                horizontalArrangement = Arrangement.spacedBy(2.dp),
                verticalItemSpacing = 2.dp,
                content = {
                    topAnimeList.itemSnapshotList.items.forEach { topAnime ->
                        items(topAnime.data.size) { index ->
                            TopAnimeItem(topAnime.data[index])
                        }
                    }
                },
                modifier = modifier.fillMaxSize()
            )
        }
    }
}

API 的响应示例附在图片上

Example API response

我想要正常的行为。当用户向下滚动时,它将请求下一页数据,而不是在开始时一遍又一遍地请求,即使它处于空闲状态。

android kotlin android-jetpack-compose paging
1个回答
0
投票

增加 pageSize = 40 并在您的服务中添加订单(“SELECT * FROM HomeFeedTable order by postId”)

© www.soinside.com 2019 - 2024. All rights reserved.