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.
您可能遇到以下问题:重新创建“ Activity
/ Fragment
时, RecyclerView
失去滚动位置。 这通常是因为Adapter
数据是异步加载的,而RecyclerView
需要进行布局RecyclerView
没有加载数据,因此它无法恢复滚动位置。
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.
从1.2.0-alpha02
, RecyclerView
提供了一个新的API,可让Adapter
阻止布局恢复直到准备就绪 。 继续阅读以了解如何使用此新API及其工作方式。
恢复滚动位置 (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.
有几种方法可以确保您可能已采用正确的滚动位置。 最好的方法是通过在缓存中, ViewModel
或存储库中缓存要显示的数据,确保始终在第一个布局通过之前在Adapter
上设置数据。 如果无法采用这种方法,则其他解决方案可能会更加复杂,例如避免在RecyclerView
上设置Adapter
,这可能会导致标题等项目出现问题,或者滥用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:
recyclerview:1.2.0-alpha02
解决方案是一种新的Adapter
方法,它允许您设置状态恢复策略(通过StateRestorationPolicy
枚举)。 这有3个选项:
ALLOW
— the default state, that restores theRecyclerView
state immediately, in the next layout passALLOW
— 默认状态,在下一次布局传递中立即恢复RecyclerView
状态PREVENT_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_WHEN_EMPTY
—仅在适配器不为空(adapter.getItemCount() > 0
)时才恢复RecyclerView
状态。 如果您的数据是异步加载的,则RecyclerView
会一直等到数据加载后才恢复状态。 如果您有默认项,例如Adapter
标题或加载进度指示符,那么您应该使用PREVENT
选项,除非使用ConcatAdapter
添加了默认项( 在此处查找更多信息 )。ConcatAdapter
等待其所有适配器准备就绪,然后才恢复状态。PREVENT
— all state restoration is deferred until you setALLOW
orPREVENT_WHEN_EMPTY
.PREVENT
所有状态恢复推迟到您设置ALLOW
或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 🏁👩💻👨💻!
而已! 简短而有趣的文章,让您了解RecyclerView
的惰性状态恢复功能。 开始使用🏁👩💻👨💻!
翻译自: https://medium.com/androiddevelopers/restore-recyclerview-scroll-position-a8fbdc9a9334