Android ViewPager+Fragment懒加载

懒加载原因

ViewPager默认会预加载下一页,而下一页用户不一定会浏览,加载下一页耗费了内存、流量,懒加载无疑在一定程度上提高了用户体验。然而setOffscreenPageLimit()又没有什么卵用,下边通过setUserVisibleHint的方式实现懒加载。


Android Phone.png
实现过程

isViewPrepare :表示View是否初始化完成,initView在onCreateView中调用,防止数据初始化完成而View没有初始化完成而空指针。
isFirst:是否是第一次加载,用于判断再次回到该Fragment不加载
setUserVisibleHint:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewPrepare && isFirst) {
            isFirst = false;
            initData();
        }
    }

当我仅仅重写setUserVisibleHint时,首页不会加载,而且奇怪的是当相隔多个Tab时也不会加载,有点疑惑,所以又重写了onResume方法,这下OK了。

@Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint()) {
            setUserVisibleHint(true);
        }
    }
示例代码

这里已经实现了Fragment的懒加载,但是我们没有设置setOffscreenPageLimit();,也就是说,当切换到第三个Fragment然后再回到第一个Fragment时,第一个Fragment确实没有再次加载数据,但是原有的数据也没有了,因为切换到第三个Fragment时第一个Fragment执行了onDestroyView()方法,再回到第一个Fragment时又重新执行了onCreateView()方法,但是设置setOffscreenPageLimit()又不知道该设置多少合适,因为数据是动态了,所以,就重写了destroyItem方法,注释掉就可以了,这样就不会销毁了,不知道有没有更好的办法,请各位大神明示。

private class NewsAdapter extends FragmentPagerAdapter {
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //super.destroyItem(container, position, object);
        }
    }
public class NewsInFragment extends BaseFragment {

    private String type;
    private boolean isViewPrepare = false;
    private boolean isFirst = true;

    @Override
    public int setContentView() {
        return R.layout.fragment_newsin;
    }

    @Override
    public void initView(View view) {
        type = getArguments().getString("type");
        TextView tv_content = view.findViewById(R.id.tv_content);
        tv_content.setText(type);
        isViewPrepare = true;
    }

    @Override
    public void onResume() {
        super.onResume();
        if(getUserVisibleHint()){
            setUserVisibleHint(true);
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewPrepare && isFirst) {
            isFirst = false;
            initData();
        }
    }
}