FragmentPagerAdapter 以及 FragmentStatePagerAdapter 对比 以及 PagerAdapter探究
FragmentPagerAdapter以及 FragmentStatePagerAdapter都是继承自PagerAdapter,可以看到其中FragmentPagerAdapter和FragmentStatePagerAdapter覆盖的方法都不多,主要是
- instantiateItem()
- destroyItem()
- setPrimaryItem()
- finishUpdate()
- getItem()
今天主要探究的是前三个方法,对于getItem,可以看fragment saveState 以及 restoreState探究里的介绍
1.instantiateItem
FragmentPagerAdapter FragmentStatePagerAdapter
首先不一样的就是在FragmentStatePagerAdapter中,是从mFragments获取缓存的mFragments,这是因为在FragmentStatePagerAdapter的destroyItem()中是把整个Fragment通过remove去除的,因此只能从缓存中获取。而FragmentPagerAdapter则可以从mFragmentManager,因为在destroyItem中是通过detach去除,只是与activity分离,但还保留在FragmentManager中。因此可以说FragmentPagerAdapter更适合固定位置的fragment,而FragmentStatePagerAdapter适合大量的fragment。
接着就是通过getitem创建新的fragment,可以看到并没有调用mCurTransaction的commit方法,commit是在fragment的所有操作完之后调用的,在FragmentPagerAdapter和FragmentStatePagerAdapter中都是通过finishUpdate()来更新的,这一步在更底层的ViewPager源码内,FragmentPagerAdapter和FragmentStatePagerAdapter已经为我们把对fragment的操作都包装好了。
最后就是设置fragment的setUserVisibleHint方法,通过覆写fragment的setUserVisibleHint方法可以获得fragment的切换时机,在此可以看到在初始化fragment的适合都会先调用一次setUserVisibleHint(false),而调用为true则是在setPrimaryItem内。
2.destroyitem
FragmentPagerAdapter FragmentStatePagerAdapter
可以看到destroyitem的不同,一个是通过detach,一个是通过remove。
另外要说的一点就是destroyitem的调用时机与ViewPager的缓存相关,通过Viewpager的setOffscreenPageLimit方法,设置缓存数目,一旦fragment的数量大于缓存的数目就会调用destroyitem方法,因此如果想保证每一个fragment的存活,需要setOffscreenPageLimit的数目等于fragment的数目。
3.setPrimaryItem
这个方法两个adapter的实现几乎是一样的,是在ViewPager选中某一个item后调用,会把当前item的setUserVisibleHint(true)其他的item嗲用setUserVisibleHint(false)。可以通过setUserVisibleHint来实现fragment内容的懒加载,避免大量fragment同时加载。另外查看setPrimaryItem对于setUserVisibleHint的操作可以明确一点,就是只有在ViewPager中使用fragment才会触发fragment的setUserVisibleHint方法,如果没有使用这一点,fragment的setUserVisibleHint方法是不会被主动调用的。