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

从ViewPager迁移到ViewPager2后如何用FragmentStateAdapter替换Fragment

ViewPager2搭配FragmentStateAdapter实现Fragment替换的解决方案

核心原理

FragmentStateAdapter没有getItemPosition方法,它通过getItemId(int position)返回的唯一ID判断对应位置的Fragment是否需要重建,默认实现直接返回position值,因此修改对应位置的Fragment实例后,适配器无法感知变化,不会触发重建。

修改方案

1. 调整适配器代码

新增唯一标识变量,复写getItemId和containsItem方法,修改替换逻辑:

public class BottomNavigationIcon extends FragmentStateAdapter implements FragChangeListner {
    FragmentManager fm;
    Fragment tmp;
    // 新增:记录位置3的Fragment唯一标识,每次切换自增
    private long position3FragmentId = 0;

    public BottomNavigationIcon(@NonNull FragmentManager fragment, Lifecycle lc) {
        super(fragment,lc);
        this.fm=fragment;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        if (position == 1)
            return SessionFragment.getInstance();
        if (position == 2)
            return OthersFragment.newInstance();
        if (position == 3) {
            if (tmp == null)
                tmp = SettingsFragment.newInstance();
            return tmp;
        }
        return ProcessFragment.newInstance();
    }

    @Override
    public int getItemCount() {
        return 4;
    }

    // 复写返回每个位置的唯一标识
    @Override
    public long getItemId(int position) {
        if (position == 3) {
            return position3FragmentId;
        }
        // 其他位置用默认实现即可
        return super.getItemId(position);
    }

    // 复写判断指定ID对应的项是否仍存在
    @Override
    public boolean containsItem(long itemId) {
        // 只要当前ID和最新的position3FragmentId一致就认为存在
        return itemId == position3FragmentId || super.containsItem(itemId);
    }

    @Override
    public void replaceFrag() {
        // 无需手动移除旧Fragment,FragmentStateAdapter会自动处理生命周期
        tmp = AboutFragment.newInstance();
        // 标识自增,通知适配器位置3的项已变更
        position3FragmentId++;
        notifyDataSetChanged();
    }
}

2. 修正接口语法错误

你提供的接口定义存在语法问题,修改如下:

public interface FragChangeListner {
    void replaceFrag();
}

注意事项

  • 不要手动通过FragmentManager移除FragmentStateAdapter管理的Fragment,适配器会自动处理销毁和重建逻辑,手动操作可能引发内存泄漏或崩溃
  • 若需要多个位置支持动态替换,可以用SparseArray<Long>存储每个位置的标识变量,按需修改对应位置的ID即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:18:03