我是新手,刚刚学习使用 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 的响应示例附在图片上
我想要正常的行为。当用户向下滚动时,它将请求下一页数据,而不是在开始时一遍又一遍地请求,即使它处于空闲状态。
增加 pageSize = 40 并在您的服务中添加订单(“SELECT * FROM HomeFeedTable order by postId”)