ViewPager+Fragment LazyLoad最优解

转载 2016年06月01日 14:31:40

(转载)http://www.jianshu.com/p/c5d29a0c3f4c

ViewPager+Fragment LazyLoad最优解

字数764 阅读1033 评论13 

ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fragment的实现方式,那表现形式上就是一个ViewPager管理了四个Fragment,左右滑动来回切换。但是ViewPager有一个奇葩的特性叫:预加载,比如打开微信,首先看到的是第一个Tab(微信),但事实上第二个Tab(通讯录)已经加载好了。当选择第二个Tab(通讯录),第三个Tab(发现)已经加载好了,以此类推。
但上诉ViewPager+Fragment的这种组合并不完美,因为我希望用户选择了哪个Tab再去加载哪个Tab的数据,而不要去做预加载,假如当前页面和预加载页面都有大量的网络请求,可能就会比较慢,有很多请求在排队。关于这个问题,也有很偏激的做法,比如弃用ViewPager,自己手动管理Fragment,或者直接禁掉ViewPager预加载。有一种比较合适的方案是保持ViewPager预加载的特性,但是只初始化View,选择当前Tab的时候再进行网络请求。关于这一方案的实现,也是众说纷纭,千奇百怪。最后,还是选择男神Stay的方案。
直接上代码。

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

}

这是一个父类,看代码这里只有一个setUserVisibleHint需要说下,这是一个相当生僻的方法,返回值是布尔型。这个方法的返回值就是当前UI是否可见,所以在prepareFetchData方法里的判断就是当前UI可见,并且fragment已经初始化完毕,如果网络数据未加载,那么请求数据,或者需要强制刷新页面,那么也去请求数据,So easy。子Fragment只需要继承父类,实现抽象方法,在fetchData()里做网络请求或者其他耗时操作即可。再在写个子类吧。

public class PageFragment extends BasePageFragment {

    public static PageFragment newInstance(String title){
        PageFragment fragment = new PageFragment();
        Bundle args = new Bundle();
        args.putString("key_fragment_title", title);
        fragment.setArguments(args);
        return fragment;
    }

    private String title;
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        title = getArguments().getString("key_fragment_title");
        Trace.d(title + ":onCreate");
    }

    @Override
    public void onResume() {
        super.onResume();
        Trace.d(title + ":onResume");
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Trace.d(title + ":onCreateView");
        tv = new TextView(getActivity());
        return tv;
    }

    @Override
    public void fetchData() {
        tv.setText(title);
        /** * 在这里请求网络。 */
    }

}

如果你也有这样的需求或者烦恼,保证药到病除。

有同学说实践过程中遇到了些问题,比如Fragment只刷新一次,这个问题只要手动调用prepareFetchData(),传true即可强制刷新了。还有同学质疑setUserVisibleHint()和onActivityCreated()的执行先后的问题。关于这个请看下图。


1.jpg

ViewPager+Fragment LazyLoad懒加载最优解

转自:http://www.jianshu.com/p/c5d29a0c3f4c#前言ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fra...
  • aiynmimi
  • aiynmimi
  • 2017年06月15日 11:56
  • 1010

ViewPager+Fragment LazyLoad 最优解

ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fragment的实现方式,那表现形式上就是一个ViewPager管理了四个Fragment...
  • yishifu
  • yishifu
  • 2016年07月28日 16:03
  • 443

ViewPager+Fragment LazyLoad 最优解决方案

ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fragment的实现方式,那表现形式上就是一个ViewPager管理了四个Fragment...
  • jiang547860818
  • jiang547860818
  • 2017年02月14日 09:41
  • 185

图片懒加载的jQuery插件lazyLoad源码分析十八问

问题1:如何为每一个调用对象DOM元素添加自定义事件? this.each(function() { var self = this; var $...
  • liangklfang
  • liangklfang
  • 2016年01月02日 09:04
  • 1622

lazyLoad插件简单使用方法

lazyLoad插件简单使用方法
  • qq_15071769
  • qq_15071769
  • 2017年12月09日 14:14
  • 31

IOS中的懒加载lazyLoad

初步写一些自己对于lazyload的看法吧。这篇文章主要针对普通view,对于image相关的的懒加载,准备过几天研究一下在写。 懒加载,又称为延迟加载。通常用法,你有一个UITextField类型的...
  • u013082522
  • u013082522
  • 2014年02月13日 00:14
  • 3809

使用lazyload在js中动态加载其他的js和css

lazyload是一个小巧的js,css动态加载器。github: https://github.com/rgrove/lazyload 使用: // Load a single JavaScri...
  • shidaping
  • shidaping
  • 2016年07月22日 10:26
  • 877

使用 lazyload 遇到的问题

lazyload已经使用过了,这次需要用到,想着把之前做的拷贝过来吧。弄了好久,才弄好。拷贝过来,发现不行,哦,还有些代码没拷贝过来,再拷贝过来,还是不行,哦还有代码没拷贝过来,再拷贝。。。。。。总之...
  • u014181418
  • u014181418
  • 2016年07月03日 10:56
  • 744

真正的LazyLoad按需加载

有些号称延迟加载的插件其实并没有做到按需加载,只是提前将图片下载好,按需展示。这样的话,依然是多并发,只是在浏览体验上好了那么一点。而经过我的实验,发现jquery.lazyload.js这个插件可以...
  • dlming614
  • dlming614
  • 2015年10月12日 16:10
  • 1988

lazyload.js 懒惰加载框架下载及使用

以前接触过一些小插件,今天总结这些插件的用法,首先我们来总结一下懒惰加载(lazyload.js)这个插件的用法. 一、下载lazyload.js          github下载地址:ht...
  • webxiaoma
  • webxiaoma
  • 2016年12月06日 09:48
  • 2664
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ViewPager+Fragment LazyLoad最优解
举报原因:
原因补充:

(最多只允许输入30个字)