ViewPager默认的情况是要进行预加载的,这么做是为了保证滑动的流畅性。但有时候我们需要在滑动到该页面的时候再进行加载,网上有好多人说利用
ViewPager.setOffscreenPageLimit(int limit);
然而这个方法并不起作用
正确的方法应该是利用两个方法 void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint()来判断当前的fragment是否可见。
经过测试 setUserVisibleHint(boolean isVisibleToUser)方会在在 onCreate() 调用后,onCreateView()调用前执行。
在此构建一个通用 fragment,并设置boolean类型的isVisible来判断 fragment 是否可见。
import android.support.v4.app.ListFragment;
public abstract class LazyListFragment extends ListFragment {
// 当前可见标识
protected boolean isVisible;
/**
* 在这里实现Fragment数据的缓加载
* @param isVisibleToUser
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
protected void onVisible(){
lazyLoad();
}
/**
*
* 当前可见时执行的函数
*/
protected abstract void lazyLoad();
protected void onInvisible(){
}
}
让 ViewPager 里面的fragment都继承 LazyListFragment,我写了两个 fragment(分别起名为“娱乐”和“体育”),执行后查看 log 信息如下:
可以看到 ViewPager 默认启动了两个 fragment,但是只有当前可见的“娱乐” fragment 调用了 setUserVisibleHint() 方法,并设置当前可见状态为 true
还有一些童鞋可能测试后发现 fragment 没有调用setUserVisibleHint(),这是因为该方法只适用于继承了FragmentPagerAdapter 的Adapter,而继承了 FragmentStatePagerAdapter 的Adapter不会调用 fragment 的setUserVisibleHint(),具体原因还有待查实,如有大神知道,还请不吝赐教。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
最近学习到一个新的适配方法,适用于FragmentPagerAdapter以及FragmentStatePagerAdapter,代码如下:
/**
* Created by lzn on 2016/7/13.
*/
public abstract class BasePageFragment extends ListFragment {
protected boolean isViewInitiated;
protected boolean isVisibleToUser;
protected boolean isDataInitiated;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
prepareFetchData();
}
public abstract void fetchData();
public boolean prepareFetchData() {
return prepareFetchData(false);
}
private boolean prepareFetchData(boolean forceUpdate) {
if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
fetchData();
isDataInitiated = true;
return true;
}
return false;
}
}
ViewPager 里的 ListFragment 可以继承这个基类,重写 fetchData() 即可。关于上面的一种方法为何在FragmentStatePagerAdapter 中失效,等有空我再查实吧!当然如果有小伙伴知道,还请留言学习。