RecyclerView Pagination in MVVM(Model-View-ViewModel) architecture using Scroll Listener
Ajinkya Patil
Posted on October 24, 2023
Why Pagination
While using social media apps, we scroll until all posts from our social network are seen. Consider there are hundreds plus posts in your social media app. Requesting all data at once will have the following drawbacks:
- List loading time will be high.
- Rendering all data on UI at once will cause a longer wait time for the user.
What is Pagination
Requesting data in bits instead of requesting all at once is called Pagination. When you open the Instagram app and scroll, it will show a list of posts. After some posts, an indicator will be shown at the bottom and it will request new posts.
Implementation
There are 2 ways to implement Pagination in Android:
- Using RecyclerView Scroll Listener
- Using Jetpack’s Paging library. To implement using the Paging library, follow the below link:
Implementation using Scroll Listener
In your Activity/Fragment, add scroll listener as follows:
linearLayoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
binding.rvListPurchaseOrderLines.layoutManager = linearLayoutManager
binding.rvListPurchaseOrderLines.adapter = adapter
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount = linearLayoutManager.childCount
val totalItemCount = linearLayoutManager.itemCount
val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
if (!viewModel.isLoading.value!! &&
(visibleItemCount + firstVisibleItemPosition) >= totalItemCount &&
firstVisibleItemPosition >= 0) {
viewModel.fetchNextPage()
}
}
})
In View Model, request next page data as follows:
class MyFeedsViewModel(private val repository: MyFeedsRepository) : ViewModel() {
val feedsDataList: LiveData<List<MyFeedsData>> = MutableLiveData()
val isLoading: LiveData<Boolean> = MutableLiveData()
private var currentPage = 1
fun fetchNextPage() {
viewModelScope.launch {
isLoading.postValue(true)
val newData = repository.fetchData(page = currentPage)
val currentData = feedsDataList.value ?: emptyList()
(feedsDataList as MutableLiveData).postValue(currentData + newData)
isLoading.postValue(false)
currentPage++
}
}
}
In Repository, fetch data from DB, network, etc as follows:
class MyFeedsRepository {
suspend fun fetchData(page: Int): List<MyFeedsData> {
// You can fetch data from network, DB, etc.
return database.feedsListDAO().getFeedsList()
}
}
In Fragment/Activity, observe live data as follows:
viewModel.feedsDataList.observe(this, Observer { dataList ->
adapter.submitList(dataList)
})
viewModel.isLoading.observe(this, Observer { isLoading ->
if(isLoading) {
progressBar.visibility = View.VISIBLE
} else {
progressBar.visibility = View.GONE
}
})
That’s it! With this setup, your RecyclerView will fetch new pages of data as the user scrolls. Adjust the specifics of the data fetching and update logic according to your needs. Thanks for reading.
Posted on October 24, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 24, 2023