懒加载介绍
在使用viewpager(或其他容器)与多个Fragment来组合使用,ViewPager 会默认一次加载当前页面前后隔一个页面,这样把我们看不到的页面的数据也加载了,大大降低了性能,浪费初始化资源,容易造成数据混乱。然而我们就采用懒加载技术,只让用户看到的页面才会加载他的数据,大大提高效率,保证数据安全。
通过ViewPager方法setOffscreenPageLimit(int limit)的源码可以发现,ViewPager通过一定的逻辑判断来确保至少会预加载左右两侧相邻的1个页面,也就是说无法通过简单的配置做到懒加载的效果,也会预加载。
ViewPager方法setOffscreenPageLimit(int limit) 相关源码
//默认的缓存页面数量(常量)
private static final int DEFAULT_OFFSCREEN_PAGES = 1;
//缓存页面数量(变量)
private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES;
public void setOffscreenPageLimit(int limit) {
//当我们手动设置的limit数小于默认值1时,limit值会自动被赋值为默认值1(即DEFAULT_OFFSCREEN_PAGES)
if (limit < DEFAULT_OFFSCREEN_PAGES) {
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "+ DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
//经过前面的拦截判断后,将limit的值设置给mOffscreenPageLimit,用于
mOffscreenPageLimit = limit;
populate();
}
}
mOffscreenPageLimit是空闲状态下的视图层级中,当前页面任何一侧保存的页面数量,默认是1。
如何做到懒加载
主要的方法是Fragment中的setUserVisibleHint(),此方法会在onCreateView()之前执行,当viewPager中fragment改变可见状态时也会调用,当fragment 从可见到不见,或者从不可见切换到可见,都会调用此方法,使用getUserVisibleHint() 可以返回fragment是否可见状态。
onLazyLoad() 加载数据必须满足三个条件:
1.getUserVisibleHint()会返回是否可见状态,这是fragment实现懒加载的关键,只有fragment 可见才会调用onLazyLoad() 加载数据。
2.isPrepared参数在系统调用onActivityCreated时设置为true,这时onCreateView方法已调用完毕(一般我们在这方法里执行findviewbyid等方法),确保 onLazyLoad()方法不会报空指针异常。
3.isLazyLoaded确保ViewPager来回切换时BaseFragment的initData方法不会被重复调用,onLazyLoad在该Fragment的整个生命周期只调用一次,第一次调用onLazyLoad()方法后马上执行 isLazyLoaded = true。
另外我们在BaseLazyFragment 中需要在onActivityCreated()及setUserVisibleHint()方法中都调了一次lazyLoad() 方法。如果仅仅在setUserVisibleHint()调用lazyLoad(),当默认首页首先加载时会导致viewPager的首页第一次展示时没有数据显示,切换一下才会有数据。因为首页fragment的setUserVisible()在onActivityCreated() 之前调用,此时isPrepared为false 导致首页fragment 没能调用onLazyLoad()方法加载数据。
实现代码如下:
然后我们再继承这个BaseLazyFragment 实现onLazyLoad() 方法就行。他会自动控制当fragment 展现出来时,才会加载数据