编辑:要恢复完全相同的外观位置,如要使其看起来完全一样,我们需要做一些不同的事情(请参见下面的如何恢复确切的scrollY值):
保存位置和偏移量,如下所示:
LinearLayoutManager manager = (LinearLayoutManager) mRecycler.getLayoutManager();
int firstItem = manager.findFirstVisibleItemPosition();
View firstItemView = manager.findViewByPosition(firstItem);
float topOffset = firstItemView.getTop();
outState.putInt(ARGS_SCROLL_POS, firstItem);
outState.putFloat(ARGS_SCROLL_OFFSET, topOffset);
然后像这样恢复滚动:
LinearLayoutManager manager = (LinearLayoutManager) mRecycler.getLayoutManager();
manager.scrollToPositionWithOffset(mStatePos, (int) mStateOffset);
这会将列表还原到其确切的外观位置。显而易见,因为它对用户而言将是相同的,但不会具有相同的scrollY值(由于横向/纵向布局尺寸可能存在差异)。
请注意,这仅适用于LinearLayoutManager。
--- 下面如何还原确切的scrollY,这可能会使列表看起来不同 ---
像这样应用一个OnScrollListener:
private int mScrollY;
private RecyclerView.OnScrollListener mTotalScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mScrollY += dy;
}
};
这将始终将确切的滚动位置存储在mScrollY中。
将此变量存储在Bundle中,然后在状态恢复中将其恢复为其他变量,我们将其称为mStateScrollY。
在状态还原之后,并且在 RecyclerView重置所有数据之后,请使用以下命令重置滚动:
mRecyclerView.scrollBy(0, mStateScrollY);
而已。
请注意,将滚动还原到另一个变量,这一点很重要,因为将使用.scrollBy()调用OnScrollListener,随后会将mScrollY设置为mStateScrollY中存储的值。如果您不这样做,则mScrollY的滚动值将是原来的两倍(因为OnScrollListener可使用增量而不是绝对滚动)。
可以通过以下方式节省活动中的状态:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARGS_SCROLL_Y, mScrollY);
}
要恢复,请在您的onCreate()中调用它:
if(savedState != null){
mStateScrollY = savedState.getInt(ARGS_SCROLL_Y, 0);
}
片段中的状态保存工作以类似的方式进行,但是实际的状态保存需要做一些额外的工作,但是有很多文章涉及到这一点,因此您应该毫无疑问地找到保存scrollY的原理并恢复原样。