问题背景:有的场景,Viewpager在每次切换Pager的时候去请求网络数据,刷新页面,同时在不显示的时候,又不会提前去请求数据。这就涉及到了Viewpager的预加载问题。
首先分析ViewPager预加载的原因
查看ViewPager的源码,发现第三行就定义了一个DEFAULT_OFFSCREEN_PAGES的变量,同时又将这个变量赋值给了mOffscreenPageLimit的变量。从变量的命名上,可以看出就是预加载的范围。接着通过查找可以发现,ViewPager设置预加载范围的方法。
源码展示如下:
private static final int DEFAULT_OFFSCREEN_PAGES = 1;
private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES;
从代码的注释来看,可以看出,这个方法就是用来规定,预加载的范围的,但是,代码中也写明了。最小范围是1,也就是左右范围1页。
/**
* Set the number of pages that should be retained to either side of the
* current page in the view hierarchy in an idle state. Pages beyond this
* limit will be recreated from the adapter when needed.
*
* <p>This is offered as an optimization. If you know in advance the number
* of pages you will need to support or have lazy-loading mechanisms in place
* on your pages, tweaking this setting can have benefits in perceived smoothness
* of paging animations and interaction. If you have a small number of pages (3-4)
* that you can keep active all at once, less time will be spent in layout for
* newly created view subtrees as the user pages back and forth.</p>
*
* <p>You should keep this limit low, especially if your pages have complex layouts.
* This setting defaults to 1.</p>
*
* @param limit How many pages will be kept offscreen in an idle state.
*/
public void setOffscreenPageLimit(int limit) {
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) {
mOffscreenPageLimit = limit;
populate();
}
}
分析完预加载的原因,现在我们分析,如果做到,只加载当前显示页,不加载预加载的页面呢?
第一个方法,因为上述两个边路都是私有,所以使用继承好像不能解决问题,就只能完全复制ViewPager的代码来实现了。工程量有点大啊。
第二个方法,我们发现Fragment有一个方法是 setUserVisibleHint()方法,这个方法在OnCreateView方法之前调用,并且每次Fragement显示与不显示的时候都会调用
所以讲需要请求数据的接口从之前别的回调函数中转移到次方法中即可。这样也可以变相的实现Lazy Load功能
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
// TODO Auto-generated method stub
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
getValues();
}
}