FragmentPagerAdapter和FragmentStatePagerAdapter 使用场景及源码分析
2016-06-13 16:47
761 查看
FragmentPagerAdapter 和FragmentStatePagerAdapter 内部都封装有FragmentManager和FragmentTransaction,用于管理Fragment;
使用Fragment 来表示一页,显得更加简单和直观,Fragment 本身提供的一些特性可以让我们方便的对每一页进行管理,使用FragmentManager可以根据ID或TAG来查找Fragment ,
动态添加、删除、替换,Fragment 可以管理自己的生命周期,像Activity一样提供了一些生命周期回调方法
让Fragment 成为ViewPager的一页时,FragmentManager会一直保存管理创建好了的Fragment,即使当前不是显示的这一页,Fragment对象也不会被销毁,在后台默默等待重新显示。但如果Fragment不再可见时,它的视图层次会被销毁掉,下次显示时视图会重新创建
首先来分析一下FragmentPagerAdapter:
在FragmentPagerAdapter 里的instantiateItem方法实例化Fragment,首先通过TAG去找Fragment是否存在,如果不存在调用getItem()添加,子类需要复写getItem()
在destroyItem()方法中仅仅是把Fragment detach掉,Fragment界面被销毁,但是Fragment还在内存中没有销毁
因此在使用FragmentPagerAdapter 时,Fragment对象会一直存留在内存中,所以当有大量的显示页时,就不适合用FragmentPagerAdapter 了,FragmentPagerAdapter 适用于只有少数的page情况,像选项卡
接下来看FragmentStatePagerAdapter 源码:
从源码上看当使用FragmentStatePagerAdapter
时,如果Fragment不显示,那么Fragment对象会被销毁,但在回调onDestroy()方法之前会回调onSaveInstanceState(Bundle outState)方法来保存Fragment的状态,下次Fragment显示时通过onCreate(Bundle savedInstanceState)把存储的状态值取出来,FragmentStatePagerAdapter 比较适合页面比较多的情况,像一个页面的ListView
item
使用Fragment 来表示一页,显得更加简单和直观,Fragment 本身提供的一些特性可以让我们方便的对每一页进行管理,使用FragmentManager可以根据ID或TAG来查找Fragment ,
动态添加、删除、替换,Fragment 可以管理自己的生命周期,像Activity一样提供了一些生命周期回调方法
让Fragment 成为ViewPager的一页时,FragmentManager会一直保存管理创建好了的Fragment,即使当前不是显示的这一页,Fragment对象也不会被销毁,在后台默默等待重新显示。但如果Fragment不再可见时,它的视图层次会被销毁掉,下次显示时视图会重新创建
首先来分析一下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); mCurTransaction.attach(fragment); } else { fragment = getItem(position); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } return fragment; }
在FragmentPagerAdapter 里的instantiateItem方法实例化Fragment,首先通过TAG去找Fragment是否存在,如果不存在调用getItem()添加,子类需要复写getItem()
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()); mCurTransaction.detach((Fragment)object); }
在destroyItem()方法中仅仅是把Fragment detach掉,Fragment界面被销毁,但是Fragment还在内存中没有销毁
因此在使用FragmentPagerAdapter 时,Fragment对象会一直存留在内存中,所以当有大量的显示页时,就不适合用FragmentPagerAdapter 了,FragmentPagerAdapter 适用于只有少数的page情况,像选项卡
接下来看FragmentStatePagerAdapter 源码:
@Override public Object instantiateItem(ViewGroup container, int position) { // If we already have this item instantiated, there is nothing // to do. This can happen when we are restoring the entire pager // from its saved state, where the fragment manager has already // taken care of restoring the fragments we previously had instantiated. if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return f; } } if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } Fragment fragment = getItem(position); if (mSavedState.size() > position) { Fragment.SavedState fss = mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (mFragments.size() <= position) { mFragments.add(null); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); mFragments.set(position, fragment); mCurTransaction.add(container.getId(), fragment); return fragment; }
@Override public void destroyItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object + " v=" + ((Fragment)object).getView()); while (mSavedState.size() <= position) { mSavedState.add(null); } mSavedState.set(position, fragment.isAdded() ? mFragmentManager.saveFragmentInstanceState(fragment) : null); mFragments.set(position, null); mCurTransaction.remove(fragment); }
从源码上看当使用FragmentStatePagerAdapter
时,如果Fragment不显示,那么Fragment对象会被销毁,但在回调onDestroy()方法之前会回调onSaveInstanceState(Bundle outState)方法来保存Fragment的状态,下次Fragment显示时通过onCreate(Bundle savedInstanceState)把存储的状态值取出来,FragmentStatePagerAdapter 比较适合页面比较多的情况,像一个页面的ListView
item
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories