EDIT: Pour restaurer exactement la même position apparente , comme dans, la faire ressembler exactement à ce qu'elle était, nous devons faire quelque chose d'un peu différent (voir ci-dessous comment restaurer la valeur exacte scrollY):
Enregistrez la position et le décalage comme ceci:
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);
Et puis restaurez le parchemin comme ceci:
LinearLayoutManager manager = (LinearLayoutManager) mRecycler.getLayoutManager();
manager.scrollToPositionWithOffset(mStatePos, (int) mStateOffset);
Cela rétablit la liste à sa position apparente exacte . Apparent car il aura le même aspect pour l'utilisateur, mais il n'aura pas la même valeur scrollY (en raison des différences possibles dans les dimensions de la mise en page paysage / portrait).
Notez que cela ne fonctionne qu'avec LinearLayoutManager.
--- Ci-dessous comment restaurer le scrollY exact, ce qui rendra probablement la liste différente ---
Appliquez un OnScrollListener comme ceci:
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;
}
};
Cela stockera la position de défilement exacte à tout moment dans mScrollY.
Stockez cette variable dans votre Bundle et restaurez-la dans la restauration de l'état vers une variable différente , nous l'appellerons mStateScrollY.
Après la restauration de l'état et après que votre RecyclerView a réinitialisé toutes ses données, réinitialisez le défilement avec ceci:
mRecyclerView.scrollBy(0, mStateScrollY);
C'est tout.
Attention, vous restaurez le scroll vers une variable différente, c'est important, car le OnScrollListener sera appelé avec .scrollBy () et par la suite affectera mScrollY à la valeur stockée dans mStateScrollY. Si vous ne le faites pas, mScrollY aura le double de la valeur de défilement (car OnScrollListener fonctionne avec des deltas, pas des défilements absolus).
L'économie d'état dans les activités peut être réalisée comme ceci:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARGS_SCROLL_Y, mScrollY);
}
Et pour restaurer, appelez ceci dans votre onCreate ():
if(savedState != null){
mStateScrollY = savedState.getInt(ARGS_SCROLL_Y, 0);
}
La sauvegarde d'état dans les fragments fonctionne de la même manière, mais la sauvegarde d'état réelle nécessite un peu de travail supplémentaire, mais il y a beaucoup d'articles traitant de cela, vous ne devriez donc pas avoir de problème pour savoir comment, les principes de sauvegarde du parcheminY et le restaurer restent les mêmes.