在上一篇我们介绍了Fragment的基本使用,除了介绍的常规的静态加载和动态加载方式之外,其实Fragment更多的时候是与ViewPager配合使用,今天我们就来看看Fragment与ViewPager到底是怎么去使用的。
FragmentPagerAdapter与FragmentStatePagerAdapter
在使用ViewPager的时候,必不可少需要接触的就是PagerAdapter,而对于Fragment+ViewPager来说,系统提供了FragmentPagerAdapter和FragmentStatePagerAdapter。
FragmentPagerAdapter和FragmentStatePagerAdapter都是用来适配Fragment+ViewPager的,那么,二者有什么不同呢?
(1)使用的场景不同:FragmentPagerAdapter适用于装载的fragment数量较少,且页面不怎么变动的情况;FragmentStatePagerAdapter适用于装载的fragment数量较多,且页面加载的数据量很多,页面变化很大的情况。
(2)内存使用不同:FragmentPagerAdapter加载好后的fragment在fragment滑动的时候,系统只会调用detach()方法将UI从页面移除,而Fragment的实例依然会保留,由FragmentManager来管理,不会销毁Fragment的实例。而使用FragmentStatePagerAdapter系统会调用remove()方法将fragment的实例进行销毁。
Fragment懒加载
在日常开发的时候,我们知道当我们在onCreate方法里面如果做了太多请求网络数据的操作,会导致页面出现会比较慢,更多的时候是希望展示哪个页面的时候才去加载那个页面的数据,其他没有被展示出来的页面就不要去加载数据了,只有当页面显示的时候才去加载数据,而这也可以被理解为懒加载机制,即我需要的时候才加载显示。那么,在弄懂Fragment懒加载的时候,我们首先需要去了解Fragment的生命周期的执行情况。
使用FragmentPagerAdapter方式:
默认加载第一页
执行的生命周期的情况为:
(1)执行第一个Fragment的setUserVisibleHint,返回值为false。
(2)执行第二个Fragment的setUserVisibleHint,返回值为false。
(3)执行第一个Fragment的setUserVisibleHint,返回值为true。
(4)执行第一个Fragment的onAttach->onCreate。
(5)执行第二个Fragment的onAttach->onCreate。
(6)执行第一个Fragment的onCreateView->onActivityCreated->onStart->onResume。
(7)执行第二个Fragment的onCreateView->onActivityCreated->onStart->onResume。
默认加载第二页
执行的生命周期情况为:
(1)执行第二个Fragment的setUserVisibleHint,返回值为false。
(2)执行第一个Fragment的setUserVisibleHint,返回值为false。
(3)执行第三个Fragment的setUserVisibleHint,返回值为false。
(4)执行第二个Fragment的setUserVisibleHint,返回值为true。
(5)执行第二个Fragment的onAttach->onCreate。
(6)执行第一个Fragment的onAttach->onCreate。
(7)执行第三个Fragment的onAttach->onCreate。
(8)执行第二个Fragment的onCreateView->onActivityCreated->onStart->onResume。
(9)执行第一个Fragment的onCreateView->onActivityCreated。
(10)执行第三个Fragment的onCreateView->onActivityCreated。
(11)执行第一个Fragment的onStart->onResume。
(12)执行第三个Fragment的onStart->onResume。
从第一页滑到第二页
执行的生命周期情况为:
(1)执行第三个Fragment的setUserVisibleHint,返回值为false。
(2)执行第一个Fragment的setUserVisibleHint,返回值为false。
(3)执行第二个Fragment的setUserVisibleHint,返回值为true。
(4)执行第三个Fragment的onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume。
从第二页滑到第三页:
执行的生命周期的情况:
(1)执行第四个Fragment的setUserVisibleHint,返回值为false。
(2)执行第二个Fragment的setUserVisibleHint,返回值为false。
(3)执行第三个Fragment的setUserVisibleHint,返回值为true。
(4)执行第四个Fragment的onAttach->onCreate。
(5)执行第一个Fragment的onPause->onStop->onDestroyView。
(6)执行第四个Fragment的onCreateView->onActivityCreated->onStart->onResume。
从第三页滑到第四页:
执行的生命周期的情况:
(1)执行第三个Fragment的setUserVisibleHint,返回值为false。
(2)执行第四个Fragment的setUserVisibleHint,返回值为true。
(3)执行第二个Fragment的onPause->onStop->onDestroyView。
从第四页滑到到第三页:
执行的生命周期情况为:
(1)执行第二个Fragment的setUserVisibleHint,返回值为false。
(2)执行第四个Fragment的setUserVisibleHint,返回值为false。
(3)执行第三个Fragment的setUserVisibleHint,返回值为false。
(4)执行第二个Fragment的onCreateView->onActivityCreated->onStart->onResume。
总结一下:
(1)首次进入的时候,fragment的setUserVisibleHint会首先调用,执行的顺序为目标Fragment(返回值为false)->目标Fragment左边相邻(返回值为false)->目标Fragment右边相邻(返回值为false)->目标Fragment(返回值为true),如果左边或者右边没有Fragment,则不执行。
(2)Fragment滑动的时候,从左向右滑,先执行右边Fragment的setUserVisibleHint(返回值为false),再执行左边Fragment的setUserVisibleHint(返回值为false),最后执行显示Fragment的setUserVisibleHint(返回值为true)。从右向左滑,先执行左边Fragment的setUserVisibleHint(返回值为false),再执行右边Fragment的setUserVisibleHint(返回值为false),最后执行显示Fragment的setUserVisibleHint(返回值为true),如果左边或者右边没有Fragment,则不执行。
(3)Fragment的实例不会被销毁,当前展示的Fragment左右的Fragment的视图不会被销毁,其他未展示的Fragment的视图会被销毁。
(4)加载数据的时候可以通过setUserVisibleHint来进行处理。
(5)一般清况下有三个Fragment处于运行状态,一个位于前台活动,左右两个处于后台活动。
使用FragmentStatePagerAdapter方式:
默认加载第一页
执行的生命周期的情况为:
(1)执行第一个Fragment的setUserVisibleHint,返回值为false。
(2)执行第二个Fragment的setUserVisibleHint,返回值为false。
(3)执行第一个Fragment的setUserVisibleHint,返回值为true。
(4)执行第一个Fragment的onAttach->onCreate。
(5)执行第二个Fragment的onAttach->onCreate。
(6)执行第一个Fragment的onCreateView->onActivityCreated->onStart->onResume。
(7)执行第二个Fragment的onCreateView->onActivityCreated->onStart->onResume。
默认加载第二页
执行的生命周期情况为:
(1)执行第二个Fragment的setUserVisibleHint,返回值为false。
(2)执行第一个Fragment的setUserVisibleHint,返回值为false。
(3)执行第三个Fragment的setUserVisibleHint,返回值为false。
(4)执行第二个Fragment的setUserVisibleHint,返回值为true。
(5)执行第二个Fragment的onAttach->onCreate。
(6)执行第一个Fragment的onAttach->onCreate。
(7)执行第三个Fragment的onAttach->onCreate。
(8)执行第二个Fragment的onCreateView->onActivityCreated->onStart->onResume。
(9)执行第一个Fragment的onCreateView->onActivityCreated。
(10)执行第三个Fragment的onCreateView->onActivityCreated->onStart->onResume。
(11)执行第一个Fragment的onStart->onResume。
从第一页滑到第二页