ViewPager 在屏幕旋转时保留旧片段

ViewPager retaing old Fragments on screen rotation(ViewPager 在屏幕旋转时保留旧片段)

本文介绍了ViewPager 在屏幕旋转时保留旧片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using ViewPager and FragmentStatePagerAdapter to show fragment. Initially there are 2 fragments added Fragment1 and Fragment2 and 3rd fragment Fragment3 is added at 2nd position after recieiving response from server. So after all pages are added this should be sequence of Fragments in ViewPager --> Fragment1, Fragment3, Fragment2.

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

The Problem is after Fragment1 and Fragment3 are added and app is making server call before adding 3rd Fragment at 2nd position if I do screen rotation multiple time then after 3rd fragment is added it still shows old copy of Fragment2 which was at 2nd position initially at 2nd position and 3rd position have new copy of Fragment2. So Fragment3 doest shows up in ViewPager. Sequence after adding 3rd Fragment -- > Fragment1, old copy of Fragment2, New Fragment2.

我正在覆盖 onSaveInstanceState 并在我的 Activity 中调用 super.onSaveInstanceState.

I am overriding onSaveInstanceState and calling super.onSaveInstanceState in my Activity.

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

Also I have tried returning POSITION_NONE from getItemPosition. I read somewhere that ViewPager save copies of fragment. Also through debugging I checked that ViewPager contained 2 copies of Fragment2 when issue was reproduced even though getItem of FragmentStatePagerAdapter returned different Fragments for each position but still at 2nd position it was showing old fragment. For testing purpose in getItem I returned Fragment1 for all positions so that all 3 pages should be same but even after that in 2nd position it was showing old copy of Fragment2 when I reproduced issue with steps mentioned above.

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

So how to clear ViewPager so that it does not save old fragments. How to refresh ViewPager so that it does not retain old copy with fragments. I think problem is with onSaveInstanceState but I need it. How can I exclude ViewPager when views are saved in onSaveInstanceState. I have tried mViewPager.setSaveEnabled(false) but it takes too much memory.

我发现问题是适配器的instantiateItem方法没有调用getItem,因为返回的是旧片段.

I found that the problem is instantiateItem method of adapter does not call getItem due to which old fragment is returned.

下面是解决方案代码

代码:

 @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;
            }
        }

推荐答案

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

I solved the problem, I am posting my solution here. I override instantiateItem of FragmentStatePagerAdapter and inside it I am getting object from super.instantiateItem and comparing its classname with classname of object at that position from list of fragments that I am maintaining.

如果类名不同,则意味着 super.instantiateItem 返回重复片段.所以我在那个位置调用 destroyItem 并再次调用 super.instantiateItem 并从 instantiateItem 返回它.

If classname is not same its mean super.instantiateItem returns duplicate fragment. So I am calling destroyItem at that position and again calling super.instantiateItem and returning it from instantiateItem.

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

FragmentStatePagerAdapter return old fragment because in framework code arraylist mFragments has duplicate fragment and it just return fragment at current position. I think it should compare fragment at the position in list with currently displaying fragment before returning it.

这篇关于ViewPager 在屏幕旋转时保留旧片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:ViewPager 在屏幕旋转时保留旧片段