5

我正在使用ViewPagerFragmentStatePagerAdapter显示片段。最初,在收到服务器的响应后,添加了 2 个片段 Fragment1 和 Fragment2,并在第 2 个位置添加了第 3 个片段 Fragment3。因此,在添加完所有页面后,这应该是 ViewPager 中的 Fragment 序列 --> Fragment1、Fragment3、Fragment2。

问题是在添加 Fragment1 和 Fragment3 之后,如果我多次进行屏幕旋转,则应用程序在第二个位置添加第三个 Fragment 之前进行服务器调用,然后在添加第三个 Fragment2 之后,它仍然显示 Fragment2 的旧副本,该副本最初位于第二个位置位置和第三位置具有 Fragment2 的新副本。所以 Fragment3 确实出现在 ViewPager 中。添加 3rd Fragment 后的序列 --> Fragment1,Fragment2 的旧副本,New Fragment2。

我正在覆盖onSaveInstanceState并调用super.onSaveInstanceState我的活动。

我也尝试POSITION_NONE过从getItemPosition. 我在某处读到 ViewPager 保存片段的副本。同样通过调试,我检查了 ViewPager 在重现问题时是否包含 Fragment2 的 2 个副本,即使每个位置返回getItemFragmentStatePagerAdapter不同的 Fragment,但仍然在第 2 个位置显示旧片段。出于测试目的,getItem我为所有位置返回了 Fragment1,以便所有 3 个页面都应该相同,但即使在第二个位置之后,当我使用上述步骤重现问题时,它仍显示 Fragment2 的旧副本。

那么如何清除ViewPager使其不保存旧碎片。如何刷新 ViewPager 使其不保留带有片段的旧副本。我认为问题出在 onSaveInstanceState 上,但我需要它。当ViewPager视图保存在onSaveInstanceState. 我试过mViewPager.setSaveEnabled(false)了,但是它占用了太多的内存。

我发现问题是instantiateItem由于返回了旧片段,适配器的方法没有调用 getItem。

以下是解决方案代码

代码:

 @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Object obj = super.instantiateItem(container, position);
            Fragment fragment = mFragments.get(position);

            if((obj!=null && fragment!=null) && !(obj.getClass().getSimpleName().equals(fragment.clss.getSimpleName()))){
                destroyItem(container, position, obj);
                return super.instantiateItem(container, position);
            }else{
                return obj;
            }
        }
4

2 回答 2

2

仅在 FragmentpagerAdapter 中覆盖此方法

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
       // TODO Auto-generated method stub
       super.destroyItem(ViewGroup container, int position, Object object);
}

然后super.destroyItem(ViewGroup container, int position, Object object); 从您的代码中删除

于 2017-05-12T05:29:17.113 回答
1

我解决了这个问题,我在这里发布我的解决方案。我覆盖instantiateItemFragmentStatePagerAdapter在其中获取对象super.instantiateItem,并将其类名与我正在维护的片段列表中该位置的对象的类名进行比较。

如果类名不同,则其均值super.instantiateItem返回重复片段。所以我destroyItem在那个位置打电话,然后再次打电话super.instantiateItem并从instantiateItem.

FragmentStatePagerAdapter返回旧片段,因为在框架代码中,arraylistmFragments有重复的片段,它只返回当前位置的片段。我认为它应该在返回之前将列表中位置的片段与当前显示的片段进行比较。

于 2013-11-01T10:17:18.257 回答