我正在做一个Android Compose项目,在这个项目中,我使用Paging3和LazyColumn来显示从网络调用获取的项目列表.Page3的默认行为是在用户滚动时加载基于prefetchDistance的页面,但在我的例子中,它加载了大约15个页面,每个页面在屏幕启动时包含10条记录. 我试着把prefetchDistace调到10,但不起作用.

以下是我的代码: ViewModel

class ShowAllNotificationsViewModel @Inject constructor(private val pagingSource: NotificationPagingSource) :
    BaseViewModel() {


    private val _uiState =
        MutableStateFlow<UIState<BaseResponseModel<NotificationResponseModel?>>>(UIState.StateLoading)
    val uiState = _uiState.asStateFlow()

    private val _isRefreshing = MutableStateFlow(false)
    val isRefreshing = _isRefreshing.asStateFlow()


    val items: Flow<PagingData<NotificationModel>> = Pager(
        config = PagingConfig(
            pageSize = 10,
            prefetchDistance = 5,
            enablePlaceholders = false,
        ),
        pagingSourceFactory = { pagingSource }
    )
        .flow
        .cachedIn(viewModelScope)

    fun refreshData() {
        pagingSource.invalidate()
    }
}

PagingSource:

class NotificationPagingSource @Inject constructor(val requestNotificationsUseCase: GetNotificationsUseCase) :
    PagingSource<String, NotificationModel>() {

    override suspend fun load(params: LoadParams<String>): LoadResult<String, NotificationModel> {
        Timber.e(IllegalStateException())
        Timber.d("load params = $params")
        val responseModel = requestNotificationsUseCase(params.key)
        val result = responseModel?.getAsResult();
        result?.let {
            return@load when (result) {
                is Result.Error<*>,
                Result.Loading,
                is Result.SessionTimeoutError<*> -> {
                    LoadResult.Error(
                        SessionTimeoutException()
                    )
                }

                is Result.Success -> {

                    LoadResult.Page(
                        result.value.data?.notifications ?: listOf(),
                        prevKey = null,
                        nextKey = result.value.data?.lastId,
                    )
                }
            }
        }
        return LoadResult.Error(
            IllegalStateException()
        )
    }

    override fun getRefreshKey(state: PagingState<String, NotificationModel>): String? {
        Timber.d("getRefreshKey = state = $state")
        return null
    }
}

UI :

 @Composable
    fun ShowAllNotificationCompose(items: LazyPagingItems<NotificationModel>) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Black)
        ) {
            Timber.d("ShowAllNotificationCompose : state = ${items.loadState}")
            HeaderCompose()

            Box(
                modifier = Modifier
                    .weight(1f)
            ) {
                val listState = rememberLazyListState()

                LazyColumn(
                    modifier = Modifier,
                    state = listState
                ) {
                    items(
                        count = items.itemCount,
                        key = {
                            items[it]?.id ?: 0
                        }
                    ) {
                        val notificationModel = items[it]
                        if (notificationModel != null) {
                            NotificationItem(item = notificationModel)
                        } else {
                            NotificationShimmerItem()
                        }
                    }
                   if (items.loadState.append == LoadState.Loading) {
                        items(2) {
                            NotificationShimmerItem()
                        }
                    }
                }
            }
        }
    }
}

有没有办法修改这个设置,以确保分页请求只在达到prefectchDistance后才被调用. 先谢谢你了.

推荐答案

问题出在你的key分中:

key = { items[it]?.id ?: 0 }

当您呼叫LazyPagingItems::get时,它会通知Pages可以触发页面加载的项目访问.从文档中:

返回指定位置显示的项,通知分页访问项以触发完成prefetchDistance所需的任何加载.

并且立即为所有项调用key,而不仅仅是当它们被显示时.因此,对于KEY,您应该使用peek函数.或者您可以使用itemKey,它在内部使用PEEK.

key = { items.peek(it)?.id ?: 0 }

key = items.itemKey { it.id }

Android相关问答推荐

修改参数应该应用于哪些子元素?

如何在点击按钮时将字符串插入到文本字段中的光标位置?

RemoteActivityHelper.startRemoteActivity不适用于Android Wear OS 4模拟器

Android Jetpack Compose Material3主题配色方案

关闭导致Kotlin中的内存泄漏?

Android事件:APP_SCOUT_HANG警告SQLite

制作圆形SupportMapFragment

如何使用react native下载android中/data/data/[应用程序包名称文件夹]/files中的文件

在 kotlin 协同 routine 中,如何将数据范围限定为请求路径(以 MDC 为例)?

retrofit2.HttpException: HTTP 401

Android - 如何使 TextInputEditText 的高度恰好为 2 行?

如何仅同步 local_manifest.xml?

Jetpack Compose 中带有权重的行和 AnimatedVisibility 会 destruct UI

如何绘制内边框?

Android Studio电鳗:javaHome好像无效

Kotlin File(path).walkTopDown() 找不到文件

组成不重叠的元素

如何修复 api 调用在浏览器中工作但在 android studio 中为 403

在 Jetpack Compose 中 Select 要省略的文本

如何使 BasicTextField 上的光标以 jetpack compose 为中心?