Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Retain & restore recycler view scroll position
package eu.f3rog.ui.custom;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
/**
* Class {@link StatefulRecyclerView} extends {@link RecyclerView} and adds position management on configuration changes.
*
* @author FrantisekGazo
* @version 2016-03-15
*/
public final class StatefulRecyclerView
extends RecyclerView {
private static final String SAVED_SUPER_STATE = "super-state";
private static final String SAVED_LAYOUT_MANAGER = "layout-manager-state";
private Parcelable mLayoutManagerSavedState;
public StatefulRecyclerView(Context context) {
super(context);
}
public StatefulRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public StatefulRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(SAVED_SUPER_STATE, super.onSaveInstanceState());
bundle.putParcelable(SAVED_LAYOUT_MANAGER, this.getLayoutManager().onSaveInstanceState());
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mLayoutManagerSavedState = bundle.getParcelable(SAVED_LAYOUT_MANAGER);
state = bundle.getParcelable(SAVED_SUPER_STATE);
}
super.onRestoreInstanceState(state);
}
/**
* Restores scroll position after configuration change.
* <p>
* <b>NOTE:</b> Must be called after adapter has been set.
*/
private void restorePosition() {
if (mLayoutManagerSavedState != null) {
this.getLayoutManager().onRestoreInstanceState(mLayoutManagerSavedState);
mLayoutManagerSavedState = null;
}
}
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
restorePosition();
}
}
@abhimuktheeswarar

This comment has been minimized.

Copy link

@abhimuktheeswarar abhimuktheeswarar commented Sep 23, 2016

Thank you for the code, this works inside fragment 👍 , but not working inside activity 👎

@timbaev

This comment has been minimized.

Copy link

@timbaev timbaev commented Oct 3, 2016

How can I use it?

@ByErdem

This comment has been minimized.

Copy link

@ByErdem ByErdem commented Oct 14, 2016

For use:

Parcelable parce;

Save the recyclerview state:
parce = recyclerview.onSaveInstanceState();

set the recyclerview state
recyclerview.onRestoreState(parce);

You can pray for me to thank.

@Miha-x64

This comment has been minimized.

Copy link

@Miha-x64 Miha-x64 commented Jan 17, 2017

@ByErdem why do you think these methods should be called manually?

@DevangiChhatbar119

This comment has been minimized.

Copy link

@DevangiChhatbar119 DevangiChhatbar119 commented Jan 8, 2018

How can I use it..? please give some instructions.

@valterh4ck3r

This comment has been minimized.

Copy link

@valterh4ck3r valterh4ck3r commented Mar 17, 2018

Make a Readme.MD

@jrm-d

This comment has been minimized.

Copy link

@jrm-d jrm-d commented Apr 11, 2018

Hello ! It works perfectly, thanks a lot.
For people asking how to use it: import the file in your project, and just declare your StatefulRecyclerview in your layout files instead of the native "android.support.v7.widget.RecyclerView"

@jwhijazi

This comment has been minimized.

Copy link

@jwhijazi jwhijazi commented Oct 29, 2018

Error inflating class StatefulRecyclerView

@tusharpingale04

This comment has been minimized.

Copy link

@tusharpingale04 tusharpingale04 commented Feb 18, 2019

Thanks for the code. It's Working!

@MahmoudiOussama

This comment has been minimized.

Copy link

@MahmoudiOussama MahmoudiOussama commented Apr 8, 2019

Thanks a lot.
Working for me too, tested it on Android 6, 8 and 9 devices.

@backupalisher

This comment has been minimized.

Copy link

@backupalisher backupalisher commented Jul 2, 2019

How to use this one? Please tell me an example

@FrantisekGazo

This comment has been minimized.

Copy link
Owner Author

@FrantisekGazo FrantisekGazo commented Jul 3, 2019

The usage is as @jrm-d wrote:

For people asking how to use it: import the file in your project, and just declare your StatefulRecyclerview in your layout files instead of the native "android.support.v7.widget.RecyclerView"

But I didn't use it in a long time (3 years old snippet)

@backupalisher

This comment has been minimized.

Copy link

@backupalisher backupalisher commented Jul 3, 2019

Error inflating class StatefulRecyclerView

@sobhansarfi

This comment has been minimized.

Copy link

@sobhansarfi sobhansarfi commented Jul 28, 2019

How to use this code?
Please explain a full person or send an example

@sobhansarfi

This comment has been minimized.

Copy link

@sobhansarfi sobhansarfi commented Jul 29, 2019

Thank you for the code, this works inside fragment 👍 , but not working inside activity 👎
How to use this code?
Please explain a full person or send an example

@chriskikoti

This comment has been minimized.

Copy link

@chriskikoti chriskikoti commented Oct 11, 2020

Worked fine. Thanks

@chieuancucbo

This comment has been minimized.

Copy link

@chieuancucbo chieuancucbo commented Sep 9, 2021

If you are looking for a solution, don't do like that, you will never know how to use the code.

Now do like this:
All below code you put in the activity (where you using the Recyclerview)

// save position:
RecyclerView rcv = findViewById(.....);
rcv.setAdapter(....);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
rcv.setLayoutManager(layoutManager);

rcv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                pos = layoutManager.findFirstVisibleItemPosition();
               // everytime you scroll the list, new position will be saved in app's data storage:
                SharedPreferences preferences = getSharedPreferences("anyname", MODE_PRIVATE);
                SharedPreferences.Editor editor = preferences.edit();
                editor.putInt("KEY_LAST_POSITION", pos).apply();
            }
        });

// using position: 
SharedPreferences preferences = getSharedPreferences("anyname", MODE_PRIVATE);
int position = preferences.getInt("KEY_LAST_POSITION", 0); // 0 is the default value
rcv.scrollToPosition(position);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment