如果你不使用setoffscreenpagelimit(int limit)这个方法去设置默认加载数的话是会默认加载页面的左右两页的,也就是说当你进入viewpager的时候和是会被一起加载的,这样同时加载就会造成一些问题,试想我们如果设置了setoffscreenpagelimit为3的话,那么进入viewpager以后就会同时加载4个fragment,像我们平时的项目中在这些fragment中一般都是会发送网络请求的,也就是说我们有4个fragment同时发送网络请求去获取数据,这样的结果显而易见给用户的体验是不好的(如:浪费用户流量,造成卡顿等等)。
2、懒加载的实现弊端ViewPager的预加载机制。默认缓存当前页面的前后各一个。
public void setOffscreenPageLimit(int limit) { if (limit < 1) { Log.w("ViewPager", "Requested offscreen page limit " + limit + " too small; defaulting to " + 1); limit = 1; } if (limit != this.mOffscreenPageLimit) { this.mOffscreenPageLimit = limit; this.populate(); }}
4、预加载实现/** * <pre> * @author yangchong * blog : https://github.com/yangchong211 * time : 2017/7/22 * desc : 懒加载 * revise: 懒加载时机:onCreateView()方法执行完毕 + setUserVisibleHint()方法返回true * </pre> */public abstract class BaseLazyFragment extends BaseFragment { /* * 预加载页面回调的生命周期流程: * setUserVisibleHint() -->onAttach() --> onCreate()-->onCreateView()--> * onActivityCreate() --> onStart() --> onResume() */ /** * 懒加载过 */ protected boolean isLazyLoaded = false; /** * Fragment的View加载完毕的标记 */ private boolean isPrepared = false; /** * 面可见,false表示不可见 */ @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); LogUtil.d("setUserVisibleHint---"+isVisibleToUser); //只有当fragment可见时,才进行加载数据 if (isVisibleToUser){ lazyLoad(); } } /** * 调用懒加载 * 面时停止加载数据,可以覆写此方法 if (isLazyLoaded) { stopLoad(); } } } /** * 视图销毁的时候讲Fragment是否初始化的状态变为false */ @Override public void onDestroyView() { super.onDestroyView(); isLazyLoaded = false; isPrepared = false; } /** * 面时停止加载数据,可以覆写此方法。 * 存在问题,如何停止加载网络 */ protected void stopLoad(){ } /** * 面和需要销毁页面,然后通过调用Adapter的instantiateItem和destroyItem两个方法初始化新页面和销毁不需要的页面!根据newCurrentItem和mOffscreenPageLimit计算要加载的page页面,计算出startPos和endPos根据startPos和endPos初始化页面ItemInfo,先从缓存里面获取,如果没有就调用addNewItem方法,实际调用mAdapter.instantiateItem将不需要的ItemInfo移除: mItems.remove(itemIndex),并调用mAdapter.destroyItem方法设置LayoutParams参数(包括position和widthFactor),根据position排序待绘制的View列表:mDrawingOrderedChildren,重写了getChildDrawingOrder方法最后一步获取当前显示View的焦点:currView.requestFocus(View.FOCUS_FORWARD)*/void populate(int newCurrentItem) { ItemInfo oldCurInfo = null; if (mCurItem != newCurrentItem) { oldCurInfo = infoForPosition(mCurItem); mCurItem = newCurrentItem; } if (mAdapter == null) { sortChildDrawingOrder(); return; } // Bail now if we are waiting to populate