DEV Community

Ajinkya Patil
Ajinkya Patil

Posted on • Edited on

RecyclerView Pagination in MVVM(Model-View-ViewModel) architecture using Scroll Listener

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:

https://developer.android.com/topic/libraries/architecture/paging/v3-overview?source=post_page-----19be70c31a30--------------------------------

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()
        }
    }
})
Enter fullscreen mode Exit fullscreen mode

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++
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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()
   }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
})
Enter fullscreen mode Exit fullscreen mode

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.

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay