ylliX - Online Advertising Network
5 steps to use Paging3 library with Jetpack Compose

5 steps to use Paging3 library with Jetpack Compose


I had a chance to work with the Paging 3 library, along with Jetpack Compose. This guide shares some of the basics of the paging library, along with a guide on how to implement it in any android app that is using Jetpack Compose.

So I chose to build a demo news feed app to test the paging library. This is the app.

For those of you interested in skipping the article, the GitHub link is here. So let’s begin!

I have used Hilt and KSP (Kotlin Symbol Processing — similar to KAPT) for injecting our data layer with our UI layer. The other libraries used here are Coil for displaying contact URI image.

I have also used Gradle’s version catalogs to declare dependencies in the app.

You can checkout my other articles on version catalogs and Hilt to get a deeper understanding of what is required here. For now, I’ll just share the relevant files used to add these dependencies.

libs.versions.toml
build.gradle
app/build.gradle

We also need to create a custom Application class and annotate it with @HiltAndroidApp and add it to our Manifest file.

PagingLibApp.kt

Now that we have our dependencies, we need to create a model class that holds our news api data.

NewsApiResponse.kt

Now, we should be able to create our rest api service class using Retrofit.

NewsApiService.kt

We also create a Repository class that simply fetches the list of news feed from the api service. We can use Hilt to inject the api service to our repository.

NewsRepository.kt

In the Paging 3 library, the data source concept is implemented using either PagingSource or RemoteMediator.

PagingSource is the core class that serves as the data source in the Paging3 library. It defines how the data is loaded for a paginated list. It fetches data incrementally (page by page). It supports bidirectional paging (both forward and backward) and handles errors and retries for data loading.

A PagingSource implementation involves overriding the load() function, which loads the data for a given page.

If we need to handle both local and remote data sources together (e.g., caching data in Room while fetching it from a network), we can use RemoteMediator alongside PagingSource.

In this app, we are only using NewsDataSource.

NewsDataSource.kt

This is pretty straightforward. The view model will be responsible for creating the Pager along with its configurations and send it to the UI so it can observe the data changes.

A Pager is a class that is responsible for incrementally pulling chunks of data from the PagingSource as requested by the UI. Since the Pager requires access to the PagingSource, it is typically created in the data layer where the PagingSource is defined. The second thing needed to construct a Pager is the PagingConfig which defines parameters that govern how the Pager will fetch data.

NewsViewModel.kt

Our MainActivity looks like this:

MainActivity.kt

In our activity class, we simply call a compose function called HomeScreen() . The HomeScreencomposable collects the news from the ViewModel using the collectAsLazyPagingItems() . This provides us with a list of LazyPagingItems<Article> object. This object includes the list of news items we want to display, along with the current load state of the paging data.

What is LoadState? LoadState represents the state of data loading in Paging 3. It provides information about whether a particular load operation is currently in progress, completed successfully, or failed.

LoadState objects can have three forms:

You can access these states for different loading scenarios such as initial loading (LoadType.REFRESH), appending more data (LoadType.APPEND), or refreshing(LoadType.PREPEND).

We can use the loadState.refresh to check if the LoadState is loading, in error state or is successful and update the UI accordingly.

Note: I am using a custom animation here for my pager implementation. You can find that composable here.

And that’s pretty much it!



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *