You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击RecyclerView条目时如何保存其滚动状态(ViewPager+Fragment场景)

解决方案

核心问题说明

现有实现的问题主要有3个:

  • 仅保存横向滚动偏移值,且用固定100ms延迟触发滚动,RecyclerView未完成布局时滚动操作会失效,导致状态恢复失败
  • 临时状态存在SharedPreferences中,读写效率低且没有必要,跨Fragment的临时状态直接在宿主Activity中维护即可
  • 仅在Fragment初始化时传入一次滚动值,后续用户手动滑动RecyclerView的状态没有更新保存,切换页面再返回就会重置

具体修改步骤

1. 宿主Activity修改

首先在TvShowEpisodeDetails中新增成员变量,维护全局状态:

// 存储每个页面对应的RecyclerView滚动状态
private SparseArray<Parcelable> mRvScrollStates = new SparseArray<>();
// 存储全局共享的滚动值,供新建Fragment使用
private int mGlobalScrollValue = 0;

然后实现Fragment回调的sendText方法:

@Override
public void sendText(int selectedPos, int scrollValue) {
    // 保存最新滚动值
    mGlobalScrollValue = scrollValue;
    // 切换ViewPager到选中的页面
    mViewPager.setCurrentItem(selectedPos);
}
// 新增供Fragment调用的状态存取方法
public void saveRvScrollState(int pagePosition, Parcelable state) {
    mRvScrollStates.put(pagePosition, state);
}
public Parcelable getRvScrollState(int pagePosition) {
    return mRvScrollStates.get(pagePosition);
}

同时调整ViewPager的缓存策略,避免页面频繁销毁重建:

// 页面数量不多的情况下直接缓存全部
mViewPager.setOffscreenPageLimit(mEpisodes.size());

2. Fragment修改

调整onViewCreated中的状态恢复逻辑,去掉不可靠的延迟滚动:

// 原有初始化RecyclerView、LayoutManager、Adapter的代码保留
// ...
// 替换原有的延迟滚动逻辑
Parcelable scrollState = ((TvShowEpisodeDetails)requireActivity()).getRvScrollState(currentPosition);
if (scrollState != null) {
    layoutManager.onRestoreInstanceState(scrollState);
} else {
    int scrollValue = getArguments().getInt("scrollValue", 0);
    mEpisodesList.scrollBy(scrollValue, 0);
}

新增Fragment销毁时的状态保存逻辑,重写onPause方法:

@Override
public void onPause() {
    super.onPause();
    if (mEpisodesList != null && mEpisodesList.getLayoutManager() != null) {
        int currentPagePos = getArguments().getInt("position");
        Parcelable state = mEpisodesList.getLayoutManager().onSaveInstanceState();
        ((TvShowEpisodeDetails)requireActivity()).saveRvScrollState(currentPagePos, state);
    }
}

3. 可选优化

如果PlanetAdapter的选中状态需要全局同步,可以把选中位置也存在宿主Activity中,每次Fragment初始化的时候从Activity取最新的选中位置传参给Adapter,避免每个Adapter各自维护选中状态导致不同步。

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 10:00:00