web-dev-qa-db-ja.com

RecyclerViewは、アクティビティ間の状態を保存/復元します

ListViewsをRecyclerViewsに移行しています。リストビューでは、 here で説明した一般的な手法を使用して、アクティビティ間のスクロール位置を保存および復元しました。

RecyclerViewsで同じことをする方法は? RecyclerView.onSaveInstanceState()にはprotectedアクセス権があるため、直接使用することはできません。

61
khusrav

それでは、私自身の質問に答えてください。私が理解しているように、レイアウトコードとビューリサイクルコード(名前)を分離しているため、レイアウト状態を保持(および復元)するコンポーネントは、リサイクラビューで使用されるLayoutManagerです。

したがって、状態を保存するには同じパターンを使用しますが、recyclerviewではなくlayout managerで使用します。

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

より良い解決策が見つかりました-この解決策には次の利点があります。

  1. RecyclerViewの状態は電話の回転で保存および復元されます
  2. 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);
        }
    }
}
20

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)onCreateメソッドでsavedInstanceStateバンドルを確認します

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

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