屏幕旋转时刷新RecyclerView适配器并保留滚动位置的方法
解决RecyclerView刷新适配器同时保留屏幕旋转时的滚动位置
你当前的问题有两个核心原因:
- 用
getVerticalScrollbarPosition()保存位置不准确,这个方法返回的是滚动条的位置,不是列表实际的滚动偏移量 refreshAdapter()里每次新建LinearLayoutManager并重新设置,会直接清除RecyclerView的滚动状态
下面是修正后的完整方案:
1. 正确保存滚动状态
替换原来的onSaveInstanceState和onCreate逻辑,改为保存LayoutManager的完整滚动状态(包含位置和偏移量):
private Parcelable recyclerViewState; @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 保存RecyclerView的完整滚动状态 recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState(); outState.putParcelable("recycler_state", recyclerViewState); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { recyclerViewState = savedInstanceState.getParcelable("recycler_state"); } }
2. 修改刷新适配器的逻辑,先保存状态再恢复
不要每次刷新都新建LayoutManager,复用已有的即可;如果必须重新设置,也要先保存状态再恢复。调整onConfigurationChanged和refreshAdapter方法:
@Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); // 刷新前先保存当前滚动状态 recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState(); refreshAdapter(); // 刷新完成后恢复滚动状态 if (recyclerViewState != null) { recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState); } } private void refreshAdapter() { if (adapter != null) { // 仅更新数据即可,无需重复设置适配器和LayoutManager adapter.notifyDataSetChanged(); // 如果你确实需要完全替换适配器(比如数据结构变更),可以保留下面一行,但不要重复设置LayoutManager // recyclerView.setAdapter(adapter); } }
特殊情况处理:必须重新创建LayoutManager
如果屏幕旋转后需要切换LayoutManager的方向(比如横屏时改为横向列表),可以在创建新LayoutManager后立即恢复状态:
private void refreshAdapter(Configuration newConfig) { if (adapter != null) { // 先保存当前状态 Parcelable tempState = recyclerView.getLayoutManager().onSaveInstanceState(); // 根据新配置创建LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext()); layoutManager.setOrientation( newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? LinearLayoutManager.HORIZONTAL : LinearLayoutManager.VERTICAL ); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); adapter.notifyDataSetChanged(); // 恢复滚动状态 if (tempState != null) { recyclerView.getLayoutManager().onRestoreInstanceState(tempState); } } }
内容的提问来源于stack exchange,提问作者Wicaledon
相关产品推荐
相关产品推荐

