RecyclerView almacena / restaura el estado entre las actividades
Estoy migrando mis ListViews a RecyclerViews. Con listviews he utilizado la técnica común descrita aquí para almacenar y restaurar la posición de desplazamiento entre las actividades.
¿Cómo hacer lo mismo con RecyclerViews? El RecyclerView.onSaveInstanceState()
parece tener acceso protected
, por lo que no se puede utilizar directamente.
- Enumera el alineamiento de elementos con Recycler View
- Comportamiento extraño de RecyclerView después de eliminar el elemento
- NullPointerException en ViewPager con Recyclerview
- Taps rápidos (clics) en RecyclerView abre varios fragmentos
- RecyclerView BackgroundColor
- FirebaseRecyclerAdapter con vista vacía
- Recycler View Adapter con EditText
- El desplazamiento de ViewPager no funciona con RecyclerView
- Evento de toque de la manija para los artículos dentro de Recyclerview - android
- Cómo obligar a RecyclerView a desplazarse cuando no hay suficientes elementos para llenar la altura de la sceen
- AnimateLayoutChanges no funciona con RecyclerView
- Fragmento con RecyclerView: java.lang.IllegalArgumentException: Las vistas desechadas o adjuntas no se pueden reciclar. IsScrap: false isAttached: true
- Alternativa de PointToPosition para RecycleView
Ok, para responder a mi propia pregunta. Según lo entiendo, ya que han desacoplado el código de diseño y el código de reciclaje de la vista (por lo tanto, el nombre), el componente responsable de mantener el estado del diseño (y restaurarlo) es ahora el LayoutManager
utilizado en su recyclerview.
Por lo tanto, para almacenar el estado que utiliza el mismo patrón, pero en el gestor de diseño y no el recyclerview:
protected void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); // Save list state mListState = mLayoutManager.onSaveInstanceState(); state.putParcelable(LIST_STATE_KEY, mListState); }
Restaurar estado en el onRestoreInstanceState()
:
protected void onRestoreInstanceState(Bundle state) { super.onRestoreInstanceState(state); // Retrieve list state and list/item positions if(state != null) mListState = state.getParcelable(LIST_STATE_KEY); }
A continuación, actualice el LayoutManager (lo hago en onResume()
):
@Override protected void onResume() { super.onResume(); if (mListState != null) { mLayoutManager.onRestoreInstanceState(mListState); } }
He encontrado una solución mejor – esta solución tiene los siguientes beneficios:
- El estado de RecyclerView se guarda y se restaura al girar el teléfono
- El estado de RecyclerView se guarda y se restaura al volver a la actividad con RecyclerView (que no fue destruido mientras la otra actividad estaba mostrando – lo que significa que
onRestoreInstanceState()
no se llama !!)
CÓDIGO
public class ActivityItemList extends AppCompatActivity { private final String KEY_RECYCLER_STATE = "recycler_state"; private RecyclerView mRecyclerView; private static Bundle mBundleRecyclerViewState; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list);//set to whatever layout name you have mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);//set to whatever view id you use // don't forget to set your adapter } @Override protected void onPause() { super.onPause(); // save RecyclerView state mBundleRecyclerViewState = new Bundle(); Parcelable listState = mRecyclerView.getLayoutManager().onSaveInstanceState(); mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, listState); } @Override protected void onResume() { super.onResume(); // restore RecyclerView state if (mBundleRecyclerViewState != null) { Parcelable listState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE); mRecyclerView.getLayoutManager().onRestoreInstanceState(listState); } } }
Utilice este código en onPause()
y onResume()
para guardar y restaurar onResume()
private Parcelable recyclerViewState; recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();//save mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore
Esa es mi solución, restaura ambos elementos y la posición de RecyclerView
1) guardar estado de vista de reciclador en el método onSaveInstanceState
@Override protected void onSaveInstanceState(Bundle outState) { Parcelable listState = myRecyclerView.getLayoutManager().onSaveInstanceState(); // putting recyclerview position outState.putParcelable(SAVED_RECYCLER_VIEW_STATUS_ID, listState); // putting recyclerview items outState.putParcelableArrayList(SAVED_RECYCLER_VIEW_DATASET_ID,mDataset); super.onSaveInstanceState(outState); }
2) Compruebe el conjunto savedInstanceState en el método onCreate
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (mSavedInstanceState==null){ getRemoteData(); // No saved data, get data from remote }else{ restorePreviousState(); // Restore data found in the Bundle } }
3) Restaurar los datos de la vista del reciclador si la pantalla se ha girado
public void restorePreviousState(){ // getting recyclerview position mListState = mSavedInstanceState.getParcelable(SAVED_RECYCLER_VIEW_STATUS_ID); // getting recyclerview items mDataset = mSavedInstanceState.getParcelableArrayList(SAVED_RECYCLER_VIEW_DATASET_ID); // Restoring adapter items mAdapter.setItems(mDataset); // Restoring recycler view position mRvMedia.getLayoutManager().onRestoreInstanceState(mListState); }
- Viendo el mensaje en los registros: "app: theme is deprecated"?
- Buscar datos en la base de datos SQLite de Android