webentwicklung-frage-antwort-db.com.de

RecyclerView-Speicher- / Wiederherstellungsstatus zwischen Aktivitäten

Ich migriere meine ListViews zu RecyclerViews. Bei Listenansichten habe ich die allgemein beschriebene Technik verwendet hier , um die Bildlaufposition zwischen Aktivitäten zu speichern und wiederherzustellen.

Wie mache ich dasselbe mit RecyclerViews? Die RecyclerView.onSaveInstanceState() scheint protected Zugriff zu haben, kann also nicht direkt verwendet werden.

61
khusrav

Ok, um meine eigene Frage zu beantworten. Soweit ich weiß, ist die Komponente, die für das Speichern des Layoutstatus (und das Wiederherstellen des Layouts) verantwortlich ist, der in Ihrer Recyclingübersicht verwendete LayoutManager, da sie den Layoutcode und den Ansichtsrecyclingcode (also den Namen) entkoppelt haben .

Um den Status zu speichern, verwenden Sie dasselbe Muster, jedoch im Layout-Manager und nicht in der Recycling-Übersicht:

protected void onSaveInstanceState(Bundle state) {
     super.onSaveInstanceState(state);

     // Save list state
     mListState = mLayoutManager.onSaveInstanceState();
     state.putParcelable(LIST_STATE_KEY, mListState);
}

Wiederherstellungsstatus in 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);
}

Dann aktualisiere den LayoutManager (mache ich in onResume()):

@Override
protected void onResume() {
    super.onResume();

    if (mListState != null) {
        mLayoutManager.onRestoreInstanceState(mListState);
    }
}
83
khusrav

Ich habe eine bessere Lösung gefunden - Diese Lösung hat die folgenden Vorteile:

  1. Der RecyclerView-Status wird gespeichert und am Drehung des Telefons wiederhergestellt
  2. RecyclerView-Status wird gespeichert und wiederhergestellt am Rückkehr zur Aktivität mit RecyclerView (das nicht zerstört wurde, während die andere Aktivität angezeigt wurde - was bedeutet, dass onRestoreInstanceState() nicht aufgerufen wird !!)

CODE

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);
        }
    }
}
20

Verwenden Sie diesen Code in onPause() und onResume(), um die Bildlaufposition zu speichern und wiederherzustellen.

private Parcelable recyclerViewState;
recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();//save
mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore
10
mahandis mehdi

Das ist meine Lösung, sie stellt sowohl die Elemente als auch die RecyclerView-Position wieder her

1) Speichern Sie den Status der Recycler-Ansicht in der onSaveInstanceState-Methode

@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) Überprüfen Sie das savedInstanceState-Bundle in der onCreate-Methode

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState==null){
            getRemoteData(); // No saved data, get data from remote
        }else{
            restorePreviousState(); // Restore data found in the Bundle
        }
    }

3) Stellen Sie die Daten der Recycler-Ansicht wieder her, wenn der Bildschirm gedreht wurde

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);
}
7
Nicola Gallazzi
public class MainActivity extends AppCompatActivity {
Parcelable recyclerViewState;
.......
@Override
    protected void onPause() {
        super.onPause();
        recyclerViewState = MainAnecdotesView.getLayoutManager().onSaveInstanceState();//save
    }
    @Override
    protected void onResume()
    {
        super.onResume();
        if(recyclerViewState!=null)
            MainAnecdotesView.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore
    }
}
1
Vlad

Wenn Sie recyclerView.getLayoutManager().onSaveInstanceState() verwenden, vergessen Sie nicht, nach null zu suchen:

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);

    if (recyclerView != null) {
        outState.putParcelable(SCROLL_POSITION, recyclerView.getLayoutManager().onSaveInstanceState());
    }
}
0
CoolMind