Подтвердить что ты не робот

RecyclerView сохраняет/восстанавливает состояние между действиями

Я переношу свои ListViews в RecyclerViews. В списках я использовал общую технику, описанную здесь , чтобы сохранить и восстановить положение прокрутки между действиями.

Как сделать то же самое с RecyclerViews? RecyclerView.onSaveInstanceState() похоже, имеет доступ к protected, поэтому его нельзя использовать напрямую.

4b9b3361

Ответ 1

Итак, чтобы ответить на мой собственный вопрос. Насколько я понимаю, поскольку они отделили код макета и код рециркуляции вида (таким образом, имя), компонент, ответственный за сохранение состояния макета (и его восстановление), теперь является LayoutManager, используемым в вашем recyclerview.

Таким образом, чтобы сохранить состояние, вы используете тот же шаблон, но в менеджере макетов, а не recyclerview:

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

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

Восстановить состояние в 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);
}

Затем обновите LayoutManager (я делаю в onResume()):

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

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

Ответ 2

Я нашел лучшее решение - это решение имеет следующие преимущества:

  • Состояние RecyclerView сохраняется и восстанавливается при ротации телефона
  • Состояние RecyclerView сохраняется и восстанавливается на , возвращаясь к активности с помощью RecyclerView (который не был уничтожен, пока показывалось другое действие - это означает, что onRestoreInstanceState() не вызывается!!)

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

Ответ 3

Используйте этот код в onPause() и onResume() для сохранения и восстановления положения прокрутки -

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

Ответ 4

Это мое решение, оно восстанавливает оба элемента и позицию RecyclerView

1) сохранить состояние просмотра ресайклеров в методе 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) Проверить сохраненный пакетInstanceState Bundle в методе 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) Восстановить данные просмотра ресайклеров, если экран был повернут

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