apply Clean Architecture principles to recycler view pagging with Adapter Design Patterns and Jetpack Pagging

Viewed 1424

I want to build an app following clean architecture principles. There is a recycler view with pagination which asks data in the domain layer and domain gets from the Data layer as List<ToiletPaper>. I want to use Pagging lib from Jetpack, but it returns

PagedList<ToiletPaper>

Since Data and Domain layers should not be bound to any platform or frameworks I don't want to include them in these layers. How to add Jetpack Paging Library with Adapter Design Pattern without changing the Domain layer?

my source code

1 Answers

According to PagedList Docs:

All data in a PagedList is loaded from its DataSource. Creating a PagedList loads the first chunk of data from the DataSource immediately, and should for this reason be done on a background thread. The constructed PagedList may then be passed to and used on the UI thread.

In Clean Architecture, we put data sources inside Data layer. That means if you decided to use Jetpack's Paging Library, you need to import the library as a part of Data and Domain dependencies.

I will provide you step-by-step guide of how to implement it in Clean Architecture in general cases:

Data Layer

  1. Create either Room Database (recommended here) or a data source factory (the hard way).
  2. Create a method to query/get the data from the datasource, which returns DataSource.Factory.

    @Dao
    interface ToiletDao {
        @Query("SELECT * FROM toilet")
        fun getToiletPapers(): DataSource.Factory<Int, ToiletPaper>
    }
    
  3. Provide a method inside Repository to access the method you just created.

    fun getToiletPapers(): DataSource.Factory<Int, ToiletPaper> {
        return toiletDao.getToiletPapers()
    }
    

Domain Layer

Create a use case or interactor to access the getToiletPapers() from Repository, and cast it to LiveData<PagedList<>>:

class GetToiletPapers @Inject constructor(
    private val repository: ToiletRepository
) : UseCase() {

     fun execute(): DataSource.Factory<Int, ToiletPaper> {
         repository.getToiletPapers()
     }

}

Note: This class is just an example for easier explanation.

Presentation Layer

  1. In your ViewModel class, call getToiletPapers.execute().toLiveData(pageSize = 10) and store the value inside a LiveData.

  2. Use PagedListAdapter to load the data into RecyclerView.

I won't explain the detail of how to use PagedListAdapter, as there are answers of such question available in this community. Hopefully this guide will help you!

Related