Home > Software engineering >  How to handle result of paging data in compose and implement header and footer load states?
How to handle result of paging data in compose and implement header and footer load states?

Time:03-30

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?

CodePudding user response:

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() },
    )
}
  • Related