ViewPager+Fragment,FragmentPagerAdapter刷新fragment

当时做项目的时候没考虑,查了一下,就使用FragmentPagerAdapter了

然后遇到这样的问题:

比如我的城市列表是这样的:

北京、天津、上海

当我做删除北京的操作之后返回MainActivity,ViewPager显示的是北京,天津,应该是显示天津、上海

当我刚打开app定位在长春(长春会插到list的第一位),显示的是北京、天津、上海、上海

而且测试各种添加,删除城市的操作,城市会有各种乱七八糟意想不到的顺序

只有每次关闭app时,才会重新变为正常。

困扰了一上午,终于解决问题,真是哭笑不得

看了几篇FragmentPagerAdapter刷新Fragments的博客,也看了看FragmentPagerAdapter的源码

注意到instantiateItem这个方法

@SuppressWarnings("ReferenceEquality")
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

这个方法大概就是如果之前的位置缓存了Fragment,下次碰到这个位置的时候会直接取缓存,

如果没有缓存Fragment,就创建一个新的Fragment,然后把这个Fragment缓存了,方便下次用到

那这样就不难解释我之前遇到的问题了

北京、天津、上海

add一个城市的时候很正常,因为多一个position肯定那个位置是空的,会创建一个新的Fragment

delete的时候就不对劲了,删除最后面的城市也正常,删除前面的城市就会乱套了,

    把第一位的北京删了,传入了一个新的list,天津和上海,但是传入adapter的时候,

    天津是list的第一位,但是第一位缓存了一个fragment,就直接拿来用了,那么这个缓存的fragment其实是北京,

    上海是list的第二位,但是第二位也缓存了一个fragment,拿来直接用了,这个缓存的fragment是天津,

定位的时候也是一样,插入北京到第一位,但是第一位原来缓存过其他城市,并不会显示北京。

哈哈,有什么问题看看源码便清楚了,

有的博客说是要清除FragmentManager中缓存的Fragment,

或者重写instantiateItem这个方法,覆盖需要更改的Fragment,

嗯是有道理,再看看源码,好好想一下怎么重写这个方法。。。

嗯,突然看到FragmentPagerAdapter和FragmentStatePagerAdapter的区别,

嗯,之前就只知道一个适合fragment多的,另一个适合少的,也没有多了解

现在记清楚了,主要区别就是是否销毁,那么就是我所遇到的问题,哈哈哈

改为继承FragmentPagerStateAdapter,问题完美解决,我们有问题的,其实有的人早就已经想到了

想想自己也是够蠢的,不过通过这个问题,深刻的记忆了一下这个知识点,在这里记录一下

总结

看起来好像很复杂的一个问题,好像还得研究源码,最后竟然多加了一个单词解决问题,

还是自己掌握的东西比较少,平时自己看可能不知道看什么,但是项目中遇到的问题一定要记下来,

一定要注意多多学习,慢慢积累。加油!


猜你喜欢

转载自blog.csdn.net/pengbo6665631/article/details/80461453