androidandroid-jetpack-composeandroid-paging

Hide LaodingView when search have no result


I have implemented search functionality in my app which display result as a verticalGridView with pagination : https://github.com/alirezaeiii/TMDb-Compose

I have following logic for refresh load state that works as I wish :

@Composable
fun <T : TMDbItem> PagingScreen(
    viewModel: BasePagingViewModel<T>,
    onClick: (TMDbItem) -> Unit,
) {
    val lazyTMDbItems = viewModel.pagingDataFlow.collectAsLazyPagingItems()

    when (lazyTMDbItems.loadState.refresh) {
        is LoadState.Loading -> {
            TMDbProgressBar()
        }
        is LoadState.Error -> {
            val message =
                (lazyTMDbItems.loadState.refresh as? LoadState.Error)?.error?.message ?: return

            lazyTMDbItems.apply {
                ErrorScreen(
                    message = message,
                    modifier = Modifier.fillMaxSize(),
                    refresh = { retry() }
                )
            }
        }
        else -> {
            LazyTMDbItemGrid(lazyTMDbItems, onClick)
        }
    }
}

In LazyTMDbItemGrid, I try to manage append load state as follow :

@Composable
private fun <T : TMDbItem> LazyTMDbItemGrid(
    lazyTMDbItems: LazyPagingItems<T>,
    onClick: (TMDbItem) -> Unit,
) {
    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 = {

            repeat(COLUMN_COUNT) {
                item {
                    Spacer(
                        Modifier.windowInsetsTopHeight(
                            WindowInsets.statusBars.add(WindowInsets(top = 56.dp))
                        )
                    )
                }
            }

            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 -> {}
                }
            }
        })
}

The problem is when there is no result for search, or when result items is shorter than screen size, it displays LoadingRow. My expectation is when we are in this state, LoadingRow does not display, but how can I detect this state?


Solution

  • Correct me if I'm wrong but these should be dictated by the PagingSource.LoadResult.Page

    Documentation :

    Success result object for PagingSource.load. Params: data - Loaded data prevKey - Key for previous page if more data can be loaded in that direction, null otherwise. nextKey - Key for next page if more data can be loaded in that direction, null otherwise.

    So if you reached the pagination end (in either direction) :

    PagingSource.LoadResult.Page(
            data = loadedData,
            prevKey = null,
            nextKey = null)