A small Android app that shows an endlessly scrolling list of sports news, built to demonstrate the Paging 3 library with a clean, testable structure.
Originally written as a companion to the article Android Paging Library Step-By-Step Implementation Guide. The code has since moved to Paging 3 and coroutines, so it no longer matches the article's Paging 2 / RxJava code.
- Infinite scrolling with page loading, a footer spinner and a footer retry
- Pull to refresh
- Loading, empty and error states with retry
- Light and dark theme (Material 3), edge-to-edge layout
Kotlin, Paging 3, Coroutines and Flow, ViewModel, Retrofit and Gson, Coil, Material 3, View Binding.
data/remote Retrofit API, DTOs and DTO to domain mapping
data/paging PagingSource (page loading and error handling)
data NewsRepository (builds the Pager)
domain News model
di AppContainer (manual dependency injection)
ui/news Activity, ViewModel, PagingDataAdapter, load state footer
PagingDataAdapter has no add, update or remove methods. Items come from PagingData, which is
immutable, so change the data instead:
- Transform the stream in the ViewModel with
PagingData.map,filterorinsertSeparators. Keep the edits (for example removed ids) in aStateFlowand combine it with thePagerflow, so the list is rebuilt when they change. - For persistent edits, use a single source of truth such as Room with a
RemoteMediator. Write the change to the database and thePagingSourceinvalidates and reloads on its own. - Call
adapter.refresh()to reload the list from the first page.
Requires Android Studio with JDK 21 and Android SDK 37.
./gradlew assembleDebug # build
./gradlew testDebugUnitTest # unit tests
./gradlew lintDebug # lint
Unit tests cover the DTO mapper, NewsPagingSource (paging keys, end of list, errors), the API
parsing (with MockWebServer) and NewsListViewModel.
