ListViewsをRecyclerViewsに移行しています。リストビューでは、 here で説明した一般的な手法を使用して、アクティビティ間のスクロール位置を保存および復元しました。
RecyclerViewsで同じことをする方法は? RecyclerView.onSaveInstanceState()
にはprotected
アクセス権があるため、直接使用することはできません。
それでは、私自身の質問に答えてください。私が理解しているように、レイアウトコードとビューリサイクルコード(名前)を分離しているため、レイアウト状態を保持(および復元)するコンポーネントは、リサイクラビューで使用される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);
}
}
より良い解決策が見つかりました-この解決策には次の利点があります。
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);
}
}
}
onPause()
およびonResume()
でこのコードを使用して、スクロール位置を保存および復元します-
private Parcelable recyclerViewState;
recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();//save
mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore
それが私のソリューションです。アイテムと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);
}
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
}
}
recyclerView.getLayoutManager().onSaveInstanceState()
を使用するときは、nullを確認することを忘れないでください。
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (recyclerView != null) {
outState.putParcelable(SCROLL_POSITION, recyclerView.getLayoutManager().onSaveInstanceState());
}
}