I am trying to implement pagination in a vertical grid. I have successfully build it with lazyColumn (https://github.com/alirezaeiii/TMDb-Compose/blob/main/app/src/main/java/com/android/sample/tmdb/ui/paging/PagingScreen.kt), but for some reason it does not work for lazyVerticalGrid. Here is my code :
@Composable
fun <T : TMDbItem> PagingScreen(viewModel: BasePagingViewModel<T>) {
val lazyTMDbItems = viewModel.pagingDataFlow.collectAsLazyPagingItems()
LazyVerticalGrid(
columns = GridCells.Fixed(COLUMN_COUNT),
contentPadding = PaddingValues(
start = GRID_SPACING,
end = GRID_SPACING,
bottom = WindowInsets.navigationBars.getBottom(LocalDensity.current).toDp().dp.plus(
GRID_SPACING
)
),
horizontalArrangement = Arrangement.spacedBy(GRID_SPACING, Alignment.CenterHorizontally),
content = {
items(lazyTMDbItems.itemCount) { index ->
val tmdbItem = lazyTMDbItems.peek(index)
tmdbItem?.let {
TMDbItemContent(
tmdbItem,
Modifier
.height(320.dp)
.padding(vertical = GRID_SPACING)
)
}
}
lazyTMDbItems.apply {
when {
loadState.refresh is LoadState.Loading -> {
item { LoadingView(modifier = Modifier.fillMaxSize()) }
}
loadState.append is LoadState.Loading -> {
item { LoadingItem() }
}
loadState.refresh is LoadState.Error -> {
val e = lazyTMDbItems.loadState.refresh as LoadState.Error
item {
ErrorScreen(
message = e.error.localizedMessage!!,
modifier = Modifier.fillMaxSize(),
refresh = { retry() }
)
}
}
loadState.append is LoadState.Error -> {
val e = lazyTMDbItems.loadState.append as LoadState.Error
item {
ErrorScreen(
message = e.error.localizedMessage!!,
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
refresh = { retry() }
)
}
}
}
}
})
}
It loads the 1st two pages, but not the third page and later, Is there anything missing in my implementation? Code can be found here : https://github.com/alirezaeiii/TMDb-Compose/tree/Pagination-grid
CodePudding user response:
Loads are triggered by the LazyPagingItems::get
method. The other method, LazyPagingItems::peek
that you are using specifically says:
Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads.
Therefore, just calling get
instead of peek
should fix that. If you want to specify keys for your items (which you should), you have to use peek
in the key factory, because key is evaluated for all items, even those that are not visible, so calling get
there will trigger load immediately.
You can look at LazyListScope::items
extension function that is part of paging-compose library and create similar extension for LazyGridScope
.