我正在做一个Android Compose项目,我使用Paging 3沿着LazyColumn来显示从网络调用中获取的项目列表。Paging 3的默认行为是在用户滚动时加载基于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()
}
}
字符串
页面来源:
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
}
}
型
用户界面:
@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
后调用。提前感谢。
1条答案
按热度按时间lbsnaicq1#
问题出在
key
上:字符串
当您调用
LazyPagingItems::get
时,它会通知Paging可以触发页面加载的项目访问。从文档:返回在指定位置呈现的项,通知Paging该项访问以触发完成prefetchDistance所需的任何加载。
而且
key
会立即调用所有的项目,而不仅仅是在它们显示的时候。所以对于key,你应该使用peek
函数。或者你可以使用itemKey
,它在内部使用peek。型