Search code examples
androidandroid-pagingandroid-paging-library

Creating another PagingSource for a different API resource?


Suppose I have a API resource that displays a list of animals, let's call it /animals, and I have another that is used to search the list of animals using their species, /animals/{species}, if I were to use Android's new Paging3 library, would I have to create two separate PagingSourceobjects for them? The Codelab for paging has one class that extends PagingSource called GithubPagingSource, but it is only for one endpoint. I was wondering what the correct approach would be.


Solution

  • A single instance of PagingSource is supposed to represent a snapshot of the backing dataset, which basically means that if a page is dropped and reloaded by the same instance, the same page should be output.

    However, you can have one implementation and create multiple instances of it, so something like this would probably be recommendable:

    class AnimalPagingSource(val species: String?): PagingSource<..> {
        override suspend fun load(...): LoadResult<..> {
            val result = if (species != null) {
                return networkApi.getSpecies(species)
            } else {
                return networkApi.getAnimals()
            }
    
            return LoadResult.Page(result.data, ...)
        }
    }
    

    Later on when you need to use the Flow<PagingData<..>> produced by this, you can switch between multiple Pagers:

    speciesFlow
        .flatMapLatest { species ->
            Pager(...) { AnimalPagingSource(species) }.flow
        }
        .cachedIn(scope)
        .collectLatest { pagingData ->
            adapter.submitData(pagingData)
        }