预加载
ViewPager 控件有一个预加载机制,即默认情况下当前页面左右两侧的 1 个页面会被预加载,以方便用户滑动切换到相邻的界面时,更流畅地加载界面(节省了初始化时间)。
从源码里可以看到,ViewPager 的预加载机制是不可取消的,预加载数量 limit 至少为 1,如果外部设置小于 1,内部会自动置为 1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class ViewPager extends ViewGroup {
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(); } } }
|
懒加载
在 ViewPager 预加载的机制下,ViewPager 本身比较难以实现 Fragment 实例化懒加载。既然 Fragment 的实例化难以懒加载,那么退而求其次,只要求实现 Fragment 请求数据的懒加载。
我们需要从 Fragment 本身入手。
主要用到 Fragment 两个方法:
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
- public void setUserVisibleHint(boolean isVisibleToUser)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public abstract class BaseFragment { protected boolean isViewCreated; protected boolean isVisibleToUser; protected boolean isDataInitiated;
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); isViewCreated = true; lazyLoad(); }
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); this.isVisibleToUser = isVisibleToUser; if (isVisibleToUser) { lazyLoad(); } }
public boolean lazyLoad() { return lazyLoad(false); }
public boolean lazyLoad(boolean forceRefresh) { if (isVisibleToUser && isViewCreated && (!isDataInitiated || forceRefresh)) { fetchData(); isDataInitiated = true; return true; } return false; }
protected abstract void fetchData(); }
|