作者:jesusestella | 来源:互联网 | 2023-05-24 11:54
我正在将ListViews迁移到RecyclerViews.使用listviews,我使用此处描述的常用技术来存储和恢复活动之间的滚动位置.
如何使用RecyclerViews做同样的事情?在RecyclerView.onSaveInstanceState()
似乎有protected
访问权限,因此无法直接使用.
1> khusrav..:
好的,那么回答我自己的问题.据我所知,由于他们已经将布局代码和视图回收代码(因此名称)分离,因此负责保持布局状态(并恢复它)的组件现在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);
}
}
但适配器怎么样?
您可以通过消除空检查来进一步简化onRestoreInstanceState().根据Android文档:"只有存在要恢复的已保存状态时,系统才会调用onRestoreInstanceState(),因此您无需检查Bundle是否为null".这不是我的挑剔或任何东西.
如果从未调用`onRestoreInstanceState()`该怎么办?
2> Someone Some..:
我找到了更好的解决方案 - 该解决方案具有以下优势:
在手机旋转时保存并恢复RecyclerView状态
使用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);
}
}
}
为什么要在`onPause()`中保存状态?此时活动不会被破坏.国家完好无损.没有什么可以恢复的.
3> 小智..:
使用此代码onPause()
并onResume()
保存和恢复滚动位置 -
private Parcelable recyclerViewState;
recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();//save
mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore
4> Nicola Galla..:
这是我的解决方案,它恢复了物品和RecyclerView的位置
1)在onSaveInstanceState方法中保存Recycler视图状态
@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 Bundle
@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);
}
您不应使用savedInstanceState保存数据集.https://developer.android.com/topic/libraries/architecture/viewmodel.html#viewmodel_vs_savedinstancestate