0.3.0 (Sep 13, 2018)
May 31, 2018
Oct 12, 2018
Matías Irland (matir91)
Source code


A smart and simple way to work with paged endpoints. To see an example of how to use it, check out the introducing Fountain posts: part one and part two.


Fountain is an Android Kotlin library conceived to make your life easier when dealing with paged endpoint services, where the paging is based on incremental page numbers (e.g. 1, 2, 3, ...). It uses the Google Android Architecture Components, mainly the Android Paging Library to make it easier to work with paged services.

The main goal of the library is to easily provide a Listing component from a common service specification. Listing provides essentially five elements to take control of the paged list:

data class Listing<T>(
    val pagedList: LiveData<PagedList<T>>,
    val networkState: LiveData<NetworkState>,
    val refreshState: LiveData<NetworkState>,
    val refresh: () -> Unit,
    val retry: () -> Unit
  1. pagedList: A changing data stream of type T represented as a LiveData of a PagedList.
  2. networkState: A stream that notifies network state changes, such as when a new page started loading (so you can show a spinner in the UI).
  3. refresh: A refresh function, to refresh all data.
  4. refreshState: A stream that notifies the status of the refresh request.
  5. retry: A retry function to execute if something failed.

Basically, you could manage all data streams with a Listing component, which is awesome! It's really flexible and useful to display the paged list entities and reflect the network status changes in the UI.

Fountain provides two ways to generate a Listing component from paged services:

  1. Network support: Provides a Listing based on a service that uses Retrofit and RxJava. Note entities won't be saved in memory nor disk.
  2. Cache + Network support: Provides a Listing with cache support using a service based on Retrofit and RxJava, and a DataSource for caching the data. We recommend you use Room to provide the DataSource, because it will be easier. However, you could use any other DataSource.


Add library to project dependencies with JitPack.

repositories {
    maven { url "" }

dependencies {
    implementation 'com.github.xmartlabs:fountain:0.3.0'

Despite Fountain is in experimental state, we believe the API won't receive major changes.


You can read the full documentation.

Network support

The Listing with network support can be obtained using:


There's only one required structure, NetworkDataSourceAdapter<out ListResponse<Value>>, which this library uses to handle the paging. There are two methods: one to check if a page could be fetched and another one to fetch it.

interface PageFetcher<T> {
  fun fetchPage(page: Int, pageSize: Int): Single<out T>

interface NetworkDataSourceAdapter<T> : PageFetcher<T> {
  fun canFetch(page: Int, pageSize: Int): Boolean

Cache + Network support

The Listing with network and cache support can be obtained using:

  networkDataSourceAdapter = networkDataSourceAdapter,
  cachedDataSourceAdapter = cachedDataSourceAdapter

There are two required components:

  1. A NetworkDataSourceAdapter<out ListResponse<Value>> to fetch all pages.
  2. A CachedDataSourceAdapter<NetworkValue, DataSourceValue> to update the DataSource. It's the interface that the library will use to take control of the DataSource.
interface CachedDataSourceAdapter<NetworkValue, DataSourceValue> {
  fun getDataSourceFactory(): DataSource.Factory<*, DataSourceValue>

  fun saveEntities(response: List<NetworkValue>)

  fun dropEntities()

  fun runInTransaction(transaction: () -> Unit)

It has only four methods that you should implement:

  • getDataSourceFactory will be used to list the cached elements. The returned value is used to create the LivePagedListBuilder.
  • runInTransaction will be used to apply multiple DataSource operations in a single transaction. That means that if something fails, all operations will fail.
  • saveEntities will be invoked to save all entities into the DataSource. This will be executed in a transaction.
  • dropEntities will be used to delete all cached entities from the DataSource. This will be executed in a transaction.

Getting involved

  • If you want to contribute please feel free to submit pull requests.
  • If you have a feature request please open an issue.
  • If you found a bug check older issues before submitting a new one.
  • If you need help or would like to ask a general question, use StackOverflow. (Tag fountain).

Before contributing, please check the CONTRIBUTING file.


The changelog for this project can be found in the CHANGELOG file.


Made with ❤️ by XMARTLABS