it-swarm.com.ru

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

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

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

58
khusrav

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

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

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

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

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

КОД

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);
        }
    }
}
19
Someone Somewhere

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

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

Это мое решение, оно восстанавливает как элементы, так и позицию 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) Проверьте Bundle сохраненного экземпляра в методе onCreate

@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) Восстановите данные просмотра переработчика, если экран был повернут

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);
}
5
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
    }
}
0
Vlad

Когда вы используете recyclerView.getLayoutManager().onSaveInstanceState(), не забудьте проверить null:

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

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