Illustration by Ella Dobson

Restore RecyclerView scroll position

Florina Muntenescu
Android Developers
Published in
2 min readMay 4, 2020

--

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 the RecyclerView state immediately, in the next layout pass
  • PREVENT_WHEN_EMPTY — restores the RecyclerView state only when the adapter is not empty (adapter.getItemCount() > 0). If your data is loaded async, the RecyclerView 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 your Adapter, then you should use the PREVENT option, unless the default items are added using ConcatAdapter (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 set ALLOW or PREVENT_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 🏁👩‍💻👨‍💻!

--

--