ViewPager+Fragment懒加载

前言

Fragment的懒加载,在Fragment多的情况下是十分有必要的。否则要么每次切换Fragment请求数据,造成切换过程不流畅;要么设置ViewPager中Fragment的预加载数量为总的数量,一次性请求所有fragment中的数据,造成首次加载特别慢,且请求了一堆用户未必会看的页面的数据。

懒加载的实现

懒加载取前言中的中间,就是首次切换到Fragment请求数据,之后再次切换到,不再请求数据。

这部分我是看了这篇,贴一张博客中的图

Fragment生命周期部分

懒加载实现方式:

public abstract class BasePageFragment extends Fragment {

    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);
    }

    public boolean prepareFetchData(boolean forceUpdate) {
        if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
            fetchData();
            isDataInitiated = true;
            return true;
        }
        return false;
    }

}

是否向服务器请求数据,三个条件:
1、是否对用户可见,不可见的时候还没必要去加载数据
2、view是否初始化,否则因为view还没有,获取数据了怎么展示,当然会报错
3、是否已经加载过数据,这个其实也就是默认判断你是不是第一次切换到这个Fragment
至于强制更新那个忽略,可以根据自己的业务做处理。
onActivityCreated中加入请求数据的方法是为了第一个Fragment首次能加载数据。

但是需要注意的是,ViewPager默认会预加载左右两边相邻的1 个 fragment,需要在使用ViewPager的地方设置viewPager.setOffscreenPageLimit(fragment的数量);否则我们有上述的第三个条件,当你再次切换回之前的与当前Fragment相隔超过1的Fragment,页面会空,因为ViewPager并没有保存,而你也没有重新加载数据。

基于设置预加载数量为所有Fragment的数量,我截取了一部分代码的执行过程(例子中的Fragment数量为9个)


1
2
3
4
5

这五张图是进入ViewPager所在页面之后,Fragment中前面几个依次的执行顺序。图1第一个Fragment的setUserVisibleHint,参数为false,图2是第二个Fragment的setUserVisibleHint,参数为false,图3是第一个Fragment的setUserVisibleHint,参数为true,图4是第一个Fragment的onActivityCreated,图5是第二个Fragment的onActivityCreated,之后的没有截图,执行顺序就是先执行了七遍setUserVisibleHint,参数为false,再执行了七遍onActivityCreated,然后页面展示完毕。之后每次切换Fragment,调用当前Fragment的setUserVisibleHint,参数为false,调用目标Fragment的setUserVisibleHint,参数为true。

相关博文:
ViewPager+Fragment LazyLoad最优解
Fragment 数据懒加载及原理

推荐阅读更多精彩内容