So, I have an EditText on which I have set onEditorActionListener, ie after the user enters the text and presses enter/search it will fetch the details and populate the recycler view accordingly.
Now in order to save the state on a configuration change I have wrote the following code -
Parcelable stateList;
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Saving instance of the state in Parcelable stateList
stateList = recyclerView.getLayoutManager().onSaveInstanceState();
outState.putParcelable(RETAIN_STATE, stateList);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(savedInstanceState!=null) {
stateList = savedInstanceState.getParcelable(RETAIN_STATE);
recyclerView.getLayoutManager().onRestoreInstanceState(stateList);
}
}
But when I run this, and rotate the screen the recycler view does not restore the state from the stateList parcelable.
I am using MVP, so I'm setting the adapter in the callback of the presenter.
I was able to retain the state when we click on enter/search on the keyboard after the screen was rotated, so I tried this hack in the onRestoreInstanceState(), but I think there should be a better way to go about this.
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(savedInstanceState!=null) {
//The hack!
et_search.onEditorAction(EditorInfo.IME_ACTION_SEARCH);
stateList = savedInstanceState.getParcelable(RETAIN_STATE);
recyclerView.getLayoutManager().onRestoreInstanceState(stateList);
}
}
Let me know if there is more information needed. Thanks in advance.
You don't really need to call onRestoreInstanceState
on configuration change in LayoutManager because it'll be called automatically (all views have onSaveInstanceState
and onRestoreInstanceState
that's passed from life-cycle owner). Even if you want to - all you'll achieve with this is restore scroll position of views.
What you actually need to do is save data set/used in RecyclerView
adapter and set it back when screen is rotated. And then call search(or filter, whatever) again.
You can let android handle the orientation changes for you if don't want to any custom stuff by overriding config change.eg hiding some view etc
<activity android:name=".mainpage.view.MainActivity" android:configChanges="orientation|screenSize|screenLayout" >
Include this in your manifest for that activity Further to save scroll position in recyler view on rotation you can use following gist to avoid duplicate code as you can use this custom recyclerview in your project wherever same feature required
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(); } }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.