不知道你们使用ViewPager和Fragment结合的时候发现一个问题没,如果你的每个Fragment都需要请求网络数据,并且你在请求网络数据的时候会加入进度对话框的加载显示效果,当你显示第一个Fragment的时候,进度对话框并不是在你这个Fragment数据加载完成之后就停止显示了,它会等待ViewPager预加载的Fragment数据也加载完成的时候才会停止显示,即你加载第一个Fragment数据时,进度对话框的显示实际上是两个或者三个的层叠显示。

反正最近我是遇到这种情况了,下面说说我怎么解决的.

ViewPager和Fragment结合使用的时候,有两种适配器可以使用,一个是FragmentStatePagerAdapter,一个是FragmentPagerAdapter。前者在内存中最多会保留三个Fragment实例,也就是说当有Fragment切换的时候,Fragment生命周期会走onDestroyView()-->onDestroy()方法,然后创建会走onCreate()-->onCreateView()方法。但是对于后者,内存中会保留所有创建后的Fragment,也就是说当Fragment切换的时候,生命周期会走onDestroyView()和onCreateView()方法,但是不会走onDestroy()和onCreate()方法。不管是哪一种PagerAdapter,ViewPager都存在预加载Fragment的效果,为了让数据只有在Fragment显示给用户的时候才去加载,我们做了如下几件事情:

1.首先,在Fragment里面有一个方法

public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);    }

需要注意的是这个方法会在Fragment的onCreate()方法调用之前就调用,这里我们在里面作如下修改

public void setUserVisibleHint(boolean isVisibleToUser) {        if (isVisibleToUser && isVisible()){            initData();        }        super.setUserVisibleHint(isVisibleToUser);    }

initData()是加载数据的方法,不用管它。这里isVisibleToUser,如果Fragment是显示给用户的,那么这个值是true,isVisible()方法可以判断Fragment的视图是否创建好,对于第一个显示的Fragment,因为isVisibleToUSer是true,但是isVisible()是false,那么在显示第一个Fragment的时候是空白的。但是对于其它的Fragment,因为存在ViewPager的预加载,当显示到Fragment的时候,isVisible()是true,而不是false。所以会在这个方法里面进行加载数据的操作。

2.然后,我们来解决第一个Fragment显示空白的问题,我是在onCreateView()方法里面进行数据的加载操作。然后,我在这个方法里面进行如下的修改

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        //...        if (getUserVisibleHint()){            initData();        }        return inflater.inflate(R.layout.fragment_blank, container, false);    }

这里getUserVisibleHint()方法可以判断当前Fragment是否是显示给用户的,对于第一个Fragment,因为不会在setUserVisibleHint()方法里面进行数据加载操作,当走到onCreateView()方法后,会在这里判断,由于getUserVisibleHint()是true,所以会进行数据的加载。然后对于其它的Fragment来说,因为存在预加载的效果,当先走setUserVisibleHint()方法时,由于isVisibleToUser是false,所以不会进行数据的加载,而走完这个方法到达onCreateView()方法时,getUserVisibleHint()返回的是false,所以也不会进行数据的加载,只有当切换到这个Fragment的时候,会去回调setUserVisibleHint()方法,在这个方法里面进行了数据的加载操作。

以上就解决了ViewPager和Fragment结合使用的时候数据的预加载。

3.其实,我觉得上面的做法并不是完美,因为你会发现每次切换到Fragment的时候都会重新加载数据,这样是非常耗流量的。于是乎,我就想了一个办法,在Fragment里面添加了一个long的变量,用来记录Fragment刷新的时间

private long refreshTime  = 0;

然后修改setUserVisibleHint()方法,如下所示

public void setUserVisibleHint(boolean isVisibleToUser) {        if (isVisibleToUser && isVisible()){            if (refreshTime == 0 ||(refreshTime != 0 && (System.currentTimeMillis()-refreshTime) > 30 * 60 * 1000)) {                initData();            }        }        super.setUserVisibleHint(isVisibleToUser);    }

即如果这个Fragment的View视图没有被销毁的时候,只有当数据的时效性超过30min后再次切换到这个Fragment才会进行数据的加载。

4.在每次进行数据加载操作的时候对这个时间刷新,在每次View视图被重新创建的时候将时间置为0,如下所示

private void initData(){    refreshTime=System.currentTimeMillis();}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        refreshTime = 0;        //.......    }

好了,以上是关于我如何解决ViewPager和Fragment结合使用时候的数据预加载问题。其实我们还可以进行优化,对每个Fragment获取到的网络数据(一般是json)进行缓存,当每次切换的时候,先去加载本地的json数据进行展示,再去判断当前时间和这个json被缓存的时间是否超过一定的值,如果超过,再进行网络请求刷新数据。我觉得这样会更好。谢谢~晚安了,各位!

防止ViewPager和Fragment结合使用时候的数据预加载的更多相关文章

  1. ViewPager+Fragment取消预加载(延迟加载)(转)

    原文:http://www.2cto.com/kf/201501/368954.html 在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragmen ...

  2. viewpager和fragment预加载的解决

    在使用Viewpager和fragment处理中会出现预加载的问题,最近看别人的代码,终于找到了一个很好的处理方法 能有效的解决预加载的问题,在fragment都继承一个重写setUserVisibl ...

  3. Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...

  4. ViewPager+Fragment取消预加载(延迟加载)

    在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方.例如你在ViewPager中添加了三个Fragment,当加载V ...

  5. ViewPager防止Fragment销毁以及取消Fragment的预加载

    存在的问题 1. 默认情况下,ViewPager会根据setOffscreenPageLimit()方法设置的大小,自动预加载2. 还是根据setOffscreenPageLimit()方法设置的大小 ...

  6. android Viewpager取消预加载及Fragment方法的学习

    1.在使用ViewPager嵌套Fragment的时候,由于VIewPager的几个Adapter的设置来说,都会有一定的预加载.通过设置setOffscreenPageLimit(int numbe ...

  7. 巧力避免ViewPager的预加载数据,Tablayout+Fragment+viewPager

    问题描述 最近在进行一个项目的开发,其中使用到了Tablayout+Fragment+viewPager来搭建一个基本的框架,从而出现了设置数据适配器的时候,item的位置错乱问题.我打印log日志的 ...

  8. ViewPager的刷新、限制预加载、缓存所有

    [框架]: 公共部分:左侧菜单.TitleBar.RadioGroup(3个RadioButton:X.Y.Z) 选择X页面:指示器+ViewPager [要达成的效果]: (1)左侧选择A,进入X页 ...

  9. 关于禁止ViewPager预加载问题【转】

    转自:http://blog.csdn.net/qq_21898059/article/details/51453938#comments 我最近上班又遇到一个小难题了,就是如题所述:ViewPage ...

随机推荐

  1. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  2. bzoj 1493 暴力

    我们可以枚举每个点,然后求出这个点到其余点最小消耗的代价,求出比t小的且距离最大的更新答案. /**************************************************** ...

  3. ionic中登陆逻辑控制

    问题 登陆成功后从login.html调转到home.html,此时在home页面按back键又回到了login.html . 解决方案 登陆成功后,清除导航历史堆栈. 具体代码 menu.html ...

  4. codeforces 675D D. Tree Construction(线段树+BTS)

    题目链接: D. Tree Construction D. Tree Construction time limit per test 2 seconds memory limit per test ...

  5. CodeForces 706A Beru-taxi

    简单题. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #inclu ...

  6. 查看当前目录每个文件的大小(linux)

    du -sh * 查看当前目录每个文件的大小

  7. golang os包使用笔记

    zhangsan os.Stidn 标准输入 os.Stdout 标准输出 os.Stderr 标准错误输出

  8. jquery中选择器input:hidden和input[type=hidden]的区别

    关于选择器:hidden的说明,在jquery说明文档中是这样说的:匹配所有不可见元素,或者type为hidden的元素.而[type=hidden]是查找所有type属性等于hidden的元素.两者 ...

  9. topcoder srm 680 div1

    problem1 link 将限制按照$x$排序.那么$[upTo_{i}+1,upTo_{i+1}]$中数字个数为$quantity_{i+1}-quantity_{i}$.然后进行动态规划.$f[ ...

  10. C#的配置文件App.config使用总结

    应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是configuration. ...