Restore RecyclerView scroll position
You might have had the problem where a RecyclerView
loses the scroll position when your Activity
/Fragment
is re-created. This usually happens because the Adapter
data is loaded asynchronously and data hasn’t loaded by the time RecyclerView
needs to layout so it fails to restore the scroll position.
Starting with 1.2.0-alpha02
, RecyclerView
offers a new API to let the Adapter
block layout restoration until it is ready. Read on to learn how to use this new API and how it works.
Restoring the scroll position
There are several ways to ensure a correct scroll position that you might have adopted. The best one is making sure that you always set the data on the Adapter
before the first layout pass by caching the data you want to display in memory, in a ViewModel
or in a repository. If this approach wasn’t possible, other solutions were either more complicated, like avoiding setting the Adapter
on the RecyclerView
, which can bring issues with items like headers, or misusing LayoutManager.onRestoreInstanceState
API.
The recyclerview:1.2.0-alpha02
solution is a new Adapter
method which allows you to set a state restoration policy (via the StateRestorationPolicy
enum). This has 3 options:
ALLOW
— the default state, that restores theRecyclerView
state immediately, in the next layout passPREVENT_WHEN_EMPTY
— restores theRecyclerView
state only when the adapter is not empty (adapter.getItemCount() > 0
). If your data is loaded async, theRecyclerView
waits until data is loaded and only then the state is restored. If you have default items, like headers or load progress indicators as part of yourAdapter
, then you should use thePREVENT
option, unless the default items are added usingConcatAdapter
(find out more here).ConcatAdapter
waits for all of its adapters to be ready and only then it restores the state.PREVENT
— all state restoration is deferred until you setALLOW
orPREVENT_WHEN_EMPTY
.
Set the state restoration policy on the adapter like this:
adapter.stateRestorationPolicy = PREVENT_WHEN_EMPTY
That’s it! A short and sweet post to get you up to date with RecyclerView
’s lazy state restoration feature. Start using it 🏁👩💻👨💻!