Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restoring Scroll Position in Paging Library 3

I am using Paging Library 3 with a RemoteMediator which includes loading data from the network and the local Room database. Every time I scroll to a certain position in the RecyclerView, navigate away to another Fragment, and then navigate back to the Fragment with the list, the scroll state is not preserved and the RecyclerView displays the list from the very first item instead of the position I was at before I navigated away.

I have tried using StateRestorationPolicy with no luck and can't seem to figure out a way to obtain the scroll position of the PagingDataAdapter and restore it to that same exact position when navigating back to the Fragment.

In my ViewModel, I have a Flow that collects data from the RemoteMediator:

val flow = Pager(config = PagingConfig(5), remoteMediator = remoteMediator) {
    dao?.getListAsPagingSource()!!
}.flow.cachedIn(viewModelScope)

and I am submitting that data to the adapter within my Fragment:

viewLifecycleOwner.lifecycleScope.launch {
    viewModel.flow.collectLatest { pagingData ->
        adapter?.submitData(pagingData)
    }
}

At the top of the Fragment, my adapter is listed as:

class MyFragment : Fragment() {

    ...

    private var adapter: FeedAdapter? = null

    ...

    override onViewCreated(...) {

        if (adapter == null) {
            adapter = FeedAdapter(...)
        }

        recyclerView.adapter = adapter

        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.flow.collectLatest { pagingData ->
                adapter?.submitData(pagingData)
            }
        }
    }
}

How can we make sure that the adapter shows the list exactly where it was at before the user left the Fragment upon returning instead of starting the list over at the very first position?

like image 935
Calvin Rai Avatar asked May 28 '21 17:05

Calvin Rai


1 Answers

Do this in your fragment's onViewCreated:

viewLifecycleOwner.lifecycleScope.launch {
    viewModel.flow.collect { pagingData ->                
        adapter.submitData(viewLifecycleOwner.lifecycle, pagingData)
    }
}
like image 85
Gregory Kovalenko Avatar answered Nov 03 '22 03:11

Gregory Kovalenko