Reputation:
I saw many related questions about this topic, but none of them helped me. I am using a StaggeredGridLayout for my RecyclerView (showing cards). Every CardView opens a new activity, the problem I am facing is that on back press from that new activity, the RecyclerView scrolls back to the top. I want it to retain the previously scrolled position.
This what I use for now to set the layout :
rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
rv.setHasFixedSize(true);
Any proper working solution for a newbie?
EDIT :
@Override
protected void onResume() {
super.onResume();
if (listState != null) {
rvlayout.onRestoreInstanceState(listState);
}
initializeData();
}
Layout :
RecyclerView.LayoutManager rvlayout = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
and initializeData :
public void initializeData() {
rv.setLayoutManager(rvlayout);
rv.setHasFixedSize(true);
persons.clear();
c = db.rawQuery(SELECT_SQL, null);
c.moveToFirst();
if (!c.moveToFirst())
return;
while (!c.isLast()) {
id = c.getString(0);
names = c.getString(1);
age = c.getString(2);
persons.add(new Person(id,names,age));
c.moveToNext();
}
adapter = new RVAdapter(persons);
rv.setAdapter(adapter);
}
Upvotes: 3
Views: 9374
Reputation: 2091
Try to add setRetainInstance(true) in your Oncreate fragment method like this:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
The setRetainInstance(boolean retain) method Controls whether a fragment instance is retained across Activity re-creation (such as from a configuration change).
Upvotes: 0
Reputation: 1583
If you don't load the list again (when press back button) the recycler view scroll should be at the same position. Do you reload the list in onResume()?
UPDATE
I've just tried the solution that I mentioned in the comment below but with no results. I hope this code example will help you:
private int scrollPosition = 0;
private boolean shouldKeepScrollPosition = true;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(shouldKeepScrollPosition) {
MyFragment.this.scrollPosition += dy;
}
}
});
Before reload data do this:
shouldKeepScrollPosition = false;
After reload data:
shouldKeepScrollPosition = true;
recyclerView.scrollBy(0, scrollPosition);
Upvotes: 1
Reputation: 12379
use
rv.smoothScrollToPosition(position); or
rv.scrollToPosition(position);
to maintain scroll position . when u open new activity save position in a variable , sharedpreference . and call rv.smoothScrollToPosition(position)or rv.scrollToPosition(position) in initializeData();
Upvotes: 0
Reputation: 10661
The proper way to do it is to save the state of RecyclerView scroll position and restore it while switching between Activities.
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putParcelable(LIST_STATE_KEY, layoutManager.onSaveInstanceState());
}
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
Parcelable listState = state.getParcelable(LIST_STATE_KEY);
}
@Override
protected void onResume() {
super.onResume();
if (listState != null) {
layoutManager.onRestoreInstanceState(listState);
}
}
Upvotes: 8
Reputation: 1128
No idea why that's happening... but you can probably make use of startActivityForResult. Make sure you save the clicked position in the list before calling the method.
Override onActivityResult in that Activity that has your grid layout and call mRecyclerView.scrollToPosition(mLastScrolledPosition) there.
Upvotes: 0