美文网首页Android开发Android开发经验谈Android开发
Viewpager 动态改变数据 FragmentPagerAd

Viewpager 动态改变数据 FragmentPagerAd

作者: Avalon1 | 来源:发表于2019-07-23 17:31 被阅读12次

    遇到在viewpager 动态初始化fragment的问题,内存中第一次加载了三个fragment,后来有添加了一些,结果会发现原来的position的位置上的fragment是之前的出现错位的问题。

    比如 之前的viewpager中包含
    热门,活动,探索。而修改之后为热门,生活,活动,探索,这样生活的tab其实就会出现问题,会被初始化为活动。
    这个问题

    通过将FragmentPagerAdapter改为FragmentStatePagerAdapter并修改

     @Override
            public int getItemPosition(@NonNull Object object) {
                return PagerAdapter.POSITION_NONE;
            }
    

    解决了此问题,
    这个方法的默认实现是

    return PagerAdapter.POSITION_UNCHANGED

    因为,FragmentPagerAdapter 中处理缓存Fragment是将其加入FragmentManager中,

    ArrayList<Op> mOps = new ArrayList<>();
    

    这个数组在存储fragment,add方法不是在中间添加数据,所以会导致顺序问题。
    而FragmentStatePagerAdapter存储的fragment方法是不一样的,没有通过fragment管理,而是自己另外写了List保存状态等信息。
    另外需要注意的是,FragmentPagerAdapter
    的instantiateItem方法

      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;
    

    它会通过findFragmentByTag优先从已有fragment中找,所以涉及到fragment和外层交互的地方,不能简单粗暴的new一个fragment,因为它adapter中的fragment 可能和我们想象的不是同一个,

     private static String makeFragmentName(int viewId, long id) {
            return "android:switcher:" + viewId + ":" + id;
        }
    

    是通过 viewpager的id 和 position 拼接成tag。
    不过如果不遇到需要动态添加fragment的场景,应该不会出什么问题。

    相关文章

      网友评论

        本文标题:Viewpager 动态改变数据 FragmentPagerAd

        本文链接:https://www.haomeiwen.com/subject/ztmalctx.html