使用ViewPager切换Fragment时,防止频繁调用OnCreatView

Posted wangchuan886

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ViewPager切换Fragment时,防止频繁调用OnCreatView相关的知识,希望对你有一定的参考价值。

使用ViewPager切换Fragment,我原先使用系统自带的适配器FragmentPagerAdapter。

切换fragment时,频繁调用oncreatview()。

查看FragmentPagerAdapter的源码,发现两个关键的地方

@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);
           //该处使用attach导致频繁调用oncreatview
            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;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                + " v=" + ((Fragment)object).getView());
        //该处使用detach导致频繁调用oncreatview
        mCurTransaction.detach((Fragment)object);
    }

attach和detach的频繁使用导致了fragment频繁调用oncreatview。

找到元凶了,接下来就好办了。

自定义一个适配器,将attach改为show,将detach改为hide。

完美解决问题。

@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);
            //用show而不用attach,防止频繁调用oncreatview
            mCurTransaction.show(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;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                + " v=" + ((Fragment) object).getView());
        //用hide而不用detach,防止频繁调用oncreatview
        mCurTransaction.hide((Fragment) object);
    }

 

以上是关于使用ViewPager切换Fragment时,防止频繁调用OnCreatView的主要内容,如果未能解决你的问题,请参考以下文章

Fragment防止自动清理 (ViewPager滑动时,滑出屏幕后被清理)(转)

ViewPager中切换界面Fragment被销毁的问题

Android Viewpager加Fragment做界面切换时数据消失的解决方式

Android Viewpager加Fragment做界面切换时数据消失的解决方式

Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果

使用ViewPager实现三个fragment切换