我正在尝试使用带有开始和限制的jetpack compose paging 3库,它加载第一个项目,但是当我滚动列表时,它不会再次调用加载方法。
我放置了多个日志,我可以看到该方法最初只被调用一次,然后什么也没有发生。我真的不知道这里出了什么问题。这是我的代码:
常量值 PAGE_SIZE = 30
class PhotosPagingSource (private val photosApi: PhotosApi) : PagingSource<Int, Photos>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Photos> {
return try {
val page = params.key ?: 0
val start = page * PAGE_SIZE
val limit = params.loadSize
val response = photosApi.getPhotos(start, limit)
val photos = PhotosMapper.mapPhotosDTO(response)
LoadResult.Page(
data = photos,
prevKey = if (page == 0) null else page - 1,
nextKey = if (response.isEmpty()) null else page + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
override fun getRefreshKey(state: PagingState<Int, Photos>): Int? {
return state.anchorPosition
}
}
class PhotosRepositoryImpl @Inject constructor(
private val photosApi: PhotosApi,
): PhotosRepository {
override suspend fun getPhotos(): Flow<PagingData<Photos>> {
return Pager(config = PagingConfig(pageSize = 30, prefetchDistance = 3 )) {
PhotosPagingSource(photosApi)
}.flow
}
}
@HiltViewModel
class HomeViewModel @Inject constructor(
private val repository: PhotosRepository
) : ViewModel() {
init {
getPhotos()
}
private var _pagingFlow: MutableStateFlow<PagingData<Photos>> =
MutableStateFlow(value = PagingData.empty())
val pagingFlow: StateFlow<PagingData<Photos>> = _pagingFlow
private fun getPhotos() {
viewModelScope.launch(Dispatchers.IO) {
repository.getPhotos()
.distinctUntilChanged()
.cachedIn(viewModelScope)
.collect {
_pagingFlow.value = it
}
}
}
}
val lazyPagingItems = homeViewModel.pagingFlow.collectAsLazyPagingItems()
val state = lazyPagingItems.loadState
val listState = rememberLazyListState()
val pagingData = lazyPagingItems.itemSnapshotList
when {
state.refresh is LoadState.Loading && pagingData.size == 0 -> {
ShimmerHome()
}
state.refresh is LoadState.Loading && pagingData.size == 0 -> {
LoadingComposable()
}
state.refresh is LoadState.Error -> {
TODO()
}
state.append is LoadState.Loading -> {
LoadingComposable()
}
state.append is LoadState.Error -> {
TODO()
}
else -> {
LazyColumn(
modifier = Modifier,
state = listState,
contentPadding = PaddingValues(8.dp),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally,
content = {
items(items = pagingData) { pagingData ->
if (pagingData != null) {
PhotosCard(
photo = pagingData,
onCardClicked = {TODO() }
)
}
}
})
}
}
在喷气背包中,请勿使用
itemSnapshotList
,仅使用 lazyPagingItems
。问题是您必须使用 LazyPagingItems#get(index: Int)
来获取项目,并通知分页数据您即将接近页面末尾,来自文档:
返回指定位置处呈现的项目,通知 Paging 项目访问以触发满足 prefetchDistance 所需的任何加载。
使用
itemSnapshotList
寻呼机不知道您滚动到底部并需要加载另一个页面。
更新代码:
@Composable
fun PagingTest(homeViewModel: HomeViewModel = hiltViewModel()) {
val lazyPagingItems = homeViewModel.pagingFlow.collectAsLazyPagingItems()
val state = lazyPagingItems.loadState
val listState = rememberLazyListState()
when {
state.refresh is LoadState.Loading && lazyPagingItems.itemCount == 0 -> {
ShimmerHome()
}
state.refresh is LoadState.Loading && lazyPagingItems.itemCount == 0 -> {
LoadingComposable()
}
state.refresh is LoadState.Error -> {
TODO()
}
state.append is LoadState.Loading -> {
LoadingComposable()
}
state.append is LoadState.Error -> {
TODO()
}
else -> {
LazyColumn(
modifier = Modifier,
state = listState,
contentPadding = PaddingValues(8.dp),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally,
content = {
items(count = lazyPagingItems.itemCount) { index ->
lazyPagingItems.get(index = index)?.let { photo ->
PhotosCard(
photo = pagingData,
onCardClicked = { TODO() }
)
}
}
}
)
}
}
}