在开发中经常使用ViewPager+Fragment,但是你真的了解在此情景下的Fragment的生命周期吗, 使用了那么频繁, 是该好好的总结下了:
- ViewPager 中两种Adapter: FragmentPagerAdapter, FragmentStatePagerAdapter 的区别
- setOffscreenPageLimit 分析, Fragment 生命周期分析
- 在 ViewPager中 Fragment 实现懒加载的正确姿势
-
1.FragmentPagerAdapter, FragmentStatePagerAdapter 的区别
- FragmentPagerAdapter 中, 即使fragment不可见了, 他的视图可能会 destory(执行 onViewDestory, 是否执行与setOffscreenPageLimit 方法设置的值有关), 但是他的实例仍然会存在于内存中. 当较多的fragment时, 会占用较大的内存.
- FragmentSatePagerAdapter 中, 当fragment不可见时, 可能会将fragment的实例也销毁(执行 onDestory, 是否执行与setOffscreenPageLimit 方法设置的值有关). 所以内存开销会小些, 适合多fragment的情形. 2.setOffscreenPageLimit 方法分析与 Fragment生命周期分析
- setOffscreenPageLimit 方法设置的默认值是1.这个设置的值有两层含义: 一是 ViewPager 会预加载几页; 二是 ViewPager 会缓存 2*n+1 页(n为设置的值).
- 明白了setOffscreenPageLimit 方法的含义后就明白了在 ViewPager 中Fragment的生命周期了:在 FragmentPagerAdapter 中 setOffscreenPageLimit 的值影响的是 onViewDestory 方法.当缓存的 fragment 超过 setOffscreenPageLimit 设置的值后, 那些 fragment 的onViewDestory 方法会回调; 在 FragmentStatePagerAdapter 中, 当缓存的 fragment 超过 setOffscreenPageLimit 设置的值后, 那些 fragment 的onDestory 方法会回调 .
-
总结起来就一句话: ViewPager 中的 fragment 是否执行 onViewDestory 或者 onDestory 与 setOffscreenPageLimit 方法设置的值有关.
3.懒加载实现思路
- 由于ViewPager 的setScreenPageLimit 方法默认值是 1 ,所以在 ViewPager 中至少会预加载一页. 当然了预加载页面是有好处的, 但是对于页面的数据, 那就没有必要去预加载了, 如果当前加载的页面有多个请求, 又预加载下个页面的请求, 导致多个任务等待, 这会影响到当前页面的请求速度. 所以合理的做法是当页面对于用户可见时再去请求数据.
- 可能有的同学会想到, 那就在 Fragment 的 onResume 去做请求数据的操作不就行了吗! 如果真是这样 easy, 那就没必要写这篇文章了~~ 因为有预加载, 下一页的 fragment 的 onStart, onResume 方法都会执行. 怎么办?
- Fragment 里面有个方法 setUserVisibleHint(boolean isVisibleToUser) 方法. 这个方法可以判断当前页面是否对用户可见. 但是这个方法有点坑, 如果你直接在这个回调方法里面做请求, 那就坑你了,哈哈~~
- setUserVisibleHint(boolean isVisibleToUser) 这个方法的回调不是和fragment 的生命周期方法同步的, 这在官方文档中明确说明了.正确的姿势是这样的:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
nice, 完美解决!