androidandroid-jetpack-composeandroid-paging

Center loading indicator at the bottom of LazyVerticalGrid


I have implemented pagination in my app using jetpack compose. You can find full code here in case you need more details : https://github.com/alirezaeiii/TMDb-Compose

Here is my code :

LazyVerticalGrid(
        columns = GridCells.Fixed(COLUMN_COUNT),
        contentPadding = PaddingValues(
            start = Dimens.GridSpacing,
            end = Dimens.GridSpacing,
            bottom = WindowInsets.navigationBars.getBottom(LocalDensity.current)
                .toDp().dp.plus(
                    Dimens.GridSpacing
                )
        ),
        horizontalArrangement = Arrangement.spacedBy(
            Dimens.GridSpacing,
            Alignment.CenterHorizontally
        ),
        content = {

            items(lazyTMDbItems.itemCount) { index ->
                val tmdbItem = lazyTMDbItems[index]
                tmdbItem?.let {
                    TMDbItemContent(
                        it,
                        Modifier
                            .height(320.dp)
                            .padding(vertical = Dimens.GridSpacing),
                        onClick
                    )
                }
            }

            lazyTMDbItems.apply {
                when (loadState.append) {
                    is LoadState.Loading -> {
                        item(span = span) {
                            LoadingRow(modifier = Modifier.padding(vertical = Dimens.GridSpacing))
                        }
                    }
                    is LoadState.Error -> {
                        val message =
                            (loadState.append as? LoadState.Error)?.error?.message ?: return@apply

                        item(span = span) {
                            ErrorScreen(
                                message = message,
                                modifier = Modifier.padding(vertical = Dimens.GridSpacing),
                                refresh = { retry() })
                        }
                    }
                    else -> {}
                }
            }
        })

As you see I set columns as a fix size :

columns = GridCells.Fixed(COLUMN_COUNT)

And in order to set loading indicator and error view at the bottom of Grid in the middle of screen, I have :

private val span: (LazyGridItemSpanScope) -> GridItemSpan = { GridItemSpan(COLUMN_COUNT) }

So when I use it as bellow using span for items, it will be centered :

item(span = span) {
      LoadingRow(modifier = Modifier.padding(vertical = Dimens.GridSpacing))
}

My question is when columns is not a fix size. So we have :

columns = GridCells.Adaptive(minSize = 120.dp)

How can I center loading indicator and error view at the bottom of Grid in the screen? since as I understand span is working with a fix size.


Solution

  • You can use the LazyGridItemSpanScope.maxLineSpan value.

    As reported in the doc:

    The max line span (horizontal for vertical grids) an item can occupy. This will be the number of columns in vertical grids or the number of rows in horizontal grids.

    For example if LazyVerticalGrid has 3 columns this value will be 3 for each cell.

        LazyVerticalGrid(
            columns = GridCells.Adaptive(minSize = 30.dp),
        ) {
    
            items(
                listgrid,
                span = { index ->
                    GridItemSpan(maxLineSpan)
                }
            ) {
                 //...
            }
        }
    

    enter image description here