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

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

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

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

 1 @Override
 2     public Object instantiateItem(ViewGroup container, int position) {
 3         if (mCurTransaction == null) {
 4             mCurTransaction = mFragmentManager.beginTransaction();
 5         }
 6
 7         final long itemId = getItemId(position);
 8
 9         // Do we already have this fragment?
10         String name = makeFragmentName(container.getId(), itemId);
11         Fragment fragment = mFragmentManager.findFragmentByTag(name);
12         if (fragment != null) {
13             if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
14            //该处使用attach导致频繁调用oncreatview
15             mCurTransaction.attach(fragment);
16
17         } else {
18             fragment = getItem(position);
19             if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
20             mCurTransaction.add(container.getId(), fragment,
21                     makeFragmentName(container.getId(), itemId));
22         }
23         if (fragment != mCurrentPrimaryItem) {
24             fragment.setMenuVisibility(false);
25             fragment.setUserVisibleHint(false);
26         }
27
28         return fragment;
29     }
30
31     @Override
32     public void destroyItem(ViewGroup container, int position, Object object) {
33         if (mCurTransaction == null) {
34             mCurTransaction = mFragmentManager.beginTransaction();
35         }
36         if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
37                 + " v=" + ((Fragment)object).getView());
38         //该处使用detach导致频繁调用oncreatview
39         mCurTransaction.detach((Fragment)object);
40     }

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

时间: 2024-10-15 14:11:53

使用ViewPager切换Fragment时,防止频繁调用OnCreatView的相关文章

切换Fragment时实现数据保持

摘要 Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用.可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期. Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用.可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期.比如我现在在手机上有activityA和activityB,但是在平板上有更大的

FragmentTab切换Fragment时避免重复加载UI

原文地址:破晓博客 ? [原创]FragmentTab切换Fragment时避免重复加载UI 使用FragmentTa时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 测试于:Android2.3+ 解决办法:在Fragment onCreateView方法中缓存View private View rootView = null;// 缓存Fragment view @Override public

FragmentTabHost切换Fragment时避免重复加载UI

使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 解决办法:在Fragment onCreateView方法中缓存View 1 private View rootView;//缓存Fragment view 2 3 @Override 4 public View onCreateView(LayoutInflater inflater, ViewGroup conta

FragmentTabHost切换Fragment时避免重复加载UI,导致切换后重绘页面的问题解决

项目中用到了FragmentTabHost,痛苦的是切换Fragment时页面总是重新加载无法保证是切换前的状态,现在得以解决! 问题:使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 解决办法:在Fragment onCreateView方法中缓存View @Override public View onCreateView(LayoutInflater infla

(转载)解决切换Fragment时布局重新实例化

解决切换Fragment时布局重新实例化 作者 instanceof 关注 2015.12.30 17:25* 字数 628 阅读 7616评论 17喜欢 23 关于Fragment 在这简单说一下Fragment,Fragment是Android 3.0以后才出现的,是为了适应不同的手机屏幕.平板和电视机的屏幕的.另外还有一个重要的原因,因为Activity的创建到销毁需要费时费内存,大量的Activity之间的跳转会造成堆栈饱满,引发程序崩溃或者无响应.为了解决这个问题,Fragment就产

Android_ FragmentTabHost切换Fragment时避免重复加载UI

使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 解决办法:在Fragment onCreateView方法中缓存View private View rootView;//缓存Fragment view @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bu

在ViewPager中切换Fragment 不重新创建 - Android

在使用Viewpager滑动Fragment时,ViewPager只会保存当前页两边的Fragment状态.这样就会出现这样的情况: 一打开会初始化page1和page2,当手动切换到page3时page4就会初始化,但是page1就会销毁,当再切换到page1时page1就会重新初始化. 其实这是Viewpager提供的一种性能优化,叫做懒加载. 但是这种情况会导致切换时page中的布局老是重新创建,状态保存不了,体验不流畅,解决办法就是设置Viewpage的缓存页数; android.sup

Android -- ViewPager、Fragment、状态保存、通信

工程架构                                                                                      TabAFm到TabEFm都是Fragment,并且每个Fragment对应一个布局文件. TabAFm.java                                                                            package com.yydcdut.viewpag

关于FragmentManager动态管理Fragment时Fragment生命周期的探究

Fragment是Android中的重要组件,在Android 3.0的时候添加进来. 关于Fragment的生命周期,我相信了解过的开发人员都应该把以下方法脱口而出:onAttach, onCreate, onCreateView, onViewCreated, onActivityCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach. 当Fragment以静态的方式,即通过在布局文件中以