3

In View system there are official examples how to implement loading states and adding header and footer item to the list:

https://developer.android.com/topic/libraries/architecture/paging/load-state

https://github.com/android/architecture-components-samples/blob/main/PagingWithNetworkSample/app/src/main/java/com/android/example/paging/pagingwithnetwork/reddit/ui/RedditActivity.kt

I didn't really found anything similar for Jetpack Compose

Only how to show items

https://developer.android.com/jetpack/compose/lists#large-datasets

But how can we implement load states in Compose?

user924
  • 8,146
  • 7
  • 57
  • 139

1 Answers1

2

We are doing something like this, it works well:

val items by viewModel.pagedItems.collectAsLazyPagingItems()

LazyColumn() {
    if (items.loadState.prepend == LoadState.Loading) {
        item (key = "prepend_loading") { Loading() }
    }
    if (items.loadState.prepend is LoadState.Error) {
        item (key = "prepend_error") { Error() }
    }

    items(items) {}

    // the same thing with items.loadState.append
}

We also have this extension function to make it a bit easier and remove the noise from LazyColumn:

fun LazyListScope.pagingLoadStateItem(
  loadState: LoadState,
  keySuffix: String? = null,
  loading: (@Composable LazyItemScope.() -> Unit)? = null,
  error: (@Composable LazyItemScope.(LoadState.Error) -> Unit)? = null,
) {
  if (loading != null && loadState == LoadState.Loading) {
    item(
      key = keySuffix?.let { "loadingItem_$it" },
      content = loading,
    )
  }
  if (error != null && loadState is LoadState.Error) {
    item(
      key = keySuffix?.let { "errorItem_$it" },
      content = { error(loadState)},
    )
  }
}

You then use it like this:

val items by viewModel.pagedItems.collectAsLazyPagingItems()

LazyColumn() {
    pagingLoadStateItem(
        loadState = items.loadState.prepend,
        keySuffix = "prepend",
        loading = { Loading() },
        error = { Error() },
    )

    // content

    pagingLoadStateItem(
        loadState = items.loadState.append,
        keySuffix = "append",
        loading = { Loading() },
        error = { Error() },
    )
}
Jan Bína
  • 3,447
  • 14
  • 16
  • 2
    Thanks. This we can use for header and footer load states. For empty list text we can use `pagingdata.loadstate.refresh is LoadState.NotLoading && pagingdata.itemSnapshotList.isEmpty()` , for `SwipeRefresh` we can use `pagingdata.loadstate.refresh is LoadState.Loading` and for `Snackbar` error text `pagingdata.loadstate.refresh is LoadState.Error` – user924 Mar 30 '22 at 11:20