EDYCJA: Aby przywrócić dokładnie tę samą widoczną pozycję, jak w programie, aby wyglądała dokładnie tak, jak była, musimy zrobić coś innego (zobacz poniżej, jak przywrócić dokładną wartość scrollY):
Zapisz pozycję i przesunięcie w następujący sposób:
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);
A następnie przywróć zwój w ten sposób:
LinearLayoutManager manager = (LinearLayoutManager) mRecycler.getLayoutManager();
manager.scrollToPositionWithOffset(mStatePos, (int) mStateOffset);
Spowoduje to przywrócenie listy do dokładnej widocznej pozycji. Pozorny, ponieważ będzie wyglądał tak samo dla użytkownika, ale nie będzie miał takiej samej wartości scrollY (z powodu możliwych różnic w wymiarach układu poziomego / pionowego).
Zauważ, że działa to tylko z LinearLayoutManager.
--- Poniżej jak przywrócić dokładne scrollY, co prawdopodobnie sprawi, że lista będzie wyglądać inaczej ---
Zastosuj OnScrollListener w następujący sposób:
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;
}
};
Spowoduje to zapisanie dokładnej pozycji przewijania przez cały czas w mScrollY.
Przechowuj tę zmienną w swoim pakiecie i przywróć ją podczas przywracania stanu do innej zmiennej , nazwiemy ją mStateScrollY.
Po przywróceniu stanu i po zresetowaniu wszystkich danych przez RecyclerView zresetuj przewijanie za pomocą tego:
mRecyclerView.scrollBy(0, mStateScrollY);
Otóż to.
Uważaj, przywracasz przewijanie do innej zmiennej, jest to ważne, ponieważ OnScrollListener zostanie wywołany z .scrollBy (), a następnie ustawi mScrollY na wartość przechowywaną w mStateScrollY. Jeśli tego nie zrobisz, mScrollY będzie miał podwójną wartość przewijania (ponieważ OnScrollListener działa z deltami, a nie bezwzględnymi przewijaniami).
Oszczędności państwa w działaniach można osiągnąć w następujący sposób:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARGS_SCROLL_Y, mScrollY);
}
Aby przywrócić, wywołaj to w swoim onCreate ():
if(savedState != null){
mStateScrollY = savedState.getInt(ARGS_SCROLL_Y, 0);
}
Zapisywanie stanu we fragmentach działa w podobny sposób, ale faktyczne zapisywanie stanu wymaga trochę dodatkowej pracy, ale jest wiele artykułów na ten temat, więc nie powinieneś mieć problemu z ustaleniem jak, zasady zapisywania scrollY a przywrócenie pozostaje takie samo.