편집 : 에서와 같이 똑같은 명백한 위치 를 복원하려면 에서와 같이 똑같이 보이게하려면 약간 다른 작업을 수행해야합니다 (정확한 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);
그게 다야.
스크롤을 다른 변수로 복원한다는 점에 유의하십시오. OnScrollListener가 .scrollBy ()로 호출되고 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);
}
프래그먼트의 상태 저장은 비슷한 방식으로 작동하지만 실제 상태 저장에는 약간의 추가 작업이 필요하지만이를 다루는 많은 기사가 있으므로 스크롤 저장 원리를 찾는 데 문제가 없어야합니다. 복원은 동일하게 유지됩니다.