Home > Back-end >  Implement pagination in a vertical grid
Implement pagination in a vertical grid

Time:01-08

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.

  • Related