You might have had the problem where a
RecyclerView loses the scroll position when your
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.
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
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
RecyclerViewstate immediately, in the next layout pass
PREVENT_WHEN_EMPTY— restores the
RecyclerViewstate only when the adapter is not empty (
adapter.getItemCount() > 0). If your data is loaded async, the
RecyclerViewwaits 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
PREVENToption, unless the default items are added using
ConcatAdapter(find out more here).
ConcatAdapterwaits for all of its adapters to be ready and only then it restores the state.
PREVENT— all state restoration is deferred until you set
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 🏁👩💻👨💻!