使用 Jetpack Compose 的 Paging 3 库在初始加载后不调用加载方法

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

我正在尝试使用带有开始和限制的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() }
                                    )
                                }
                            }
                        })
                }
            }
android pagination android-jetpack-compose android-jetpack-compose-material3 android-native-library
1个回答
0
投票

在喷气背包中,请勿使用

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() }
                            )
                        }
                    }
                }
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.