1
Fragment 懒加载是什么意思?
所谓懒加载,即Fragment 的 UI 对用户可见时才加载数据。
以前我没啥经验,一股脑的从服务器拉取数据之后立马把数据绑定到 Fragment 的 UI 组件上,可能不符合部分产品的需求。
那么懒加载的技术关键点是什么?
根据定义:
所谓懒加载,即Fragment 的 UI 对用户可见时才加载数据。
需要判断何时 Fragment 的 UI 才对用户可见。
如何判断 Fragment 的 UI 是否对用户可见?
Fragment 提供了一个方法 public void setUserVisibleHint(boolean isVisibleToUser),API 的注释如下:
Set a hint to the system about whether this fragment's UI is currently visible to the user. This hint defaults to true and is persistent across fragment instance state save and restore.
所以,只需要判断参数 isVisibleToUser 是否为 True 即可知道该 Fragment 的 UI 是否对用户可见。
setUserVisibleHint 在什么时候调用?
对于单个 Fragment,setUserVisibleHint 是不会被调用的,只有该 Fragment 在 ViewPager 里才会被调用。所以,我写了一个 ViewPager + Fragment 的 Demo,打印了一下 Log可以看到 setUserVisibleHint 的执行顺序如下:
setUserVisibleHint: isVisibleToUser = false
onAttach
onCreate
setUserVisibleHint: isVisibleToUser = true
onCreateView
onActivityCreated
onStart
onResume
onPause
onStop
onDestroyView
onDestroy
onDetach
2
代码
为了方便,封装一个基类 LazyLoadFragment,提供一个 loadData() 方法供调用去加载数据
等等,为什么 loadData() 会在两个地方执行?
在 setUserVisibleHint 方法里执行我还能理解,为什么 onActivityCreated 也要执行呢?
因为,ViewPager 默认显示第一页,第一页肯定要先加载数据啊,而且 setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isViewCreated 的值。所以就需要在 onActivityCreated 里执行一次咯。
3
wait...
文章写到这里,我听到了一个不同的声音
ViewPager 不是有 setOffscreenPageLimit(int limit) 方法吗?我调用 viewPager.setOffscreenPageLimit(0) 不就行了吗?
我想说:思路是对的,但是这样做没效果。为什么?看一下 setOffscreenPageLimit 的方法实现就知道了
limit 默认为 1 ,就算传一个 0 也无济于事啊。(ps:留言下方有人提出可以修改ViewPager源码)
本文总结
懒加载的技术关键点
setUserVisibleHint 的执行顺序
为什么 ViewPager.setOffscreenPageLimit(0) 无效?