不知道你们使用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. MongoDB 副本集的原理、搭建、应用

    概念: 在了解了这篇文章之后,可以进行该篇文章的说明和测试.MongoDB 副本集(Replica Set)是有自动故障恢复功能的主从集群,有一个Primary节点和一个或多个Secondary节点组 ...

  2. metro中stream转IRandomAccessStream

    下面的例子是从zip压缩文件解压出jpg文件流,再显示出来. StorageFile zip = await KnownFolders.PicturesLibrary.GetFileAsync(&qu ...

  3. Django~Models1

    不用数据库不用Models 省却 --------------- startapp urls +链接 view以下 ---------------- 添加Model 在project/settings ...

  4. Urllib2 总结

    Urllib2 总结 介绍 Urllib2是用于获取URLs(统一资源定位符)的一个Python模块.它以urlopen函数的形式提供了非常简单的接口.能够使用各种不同的协议来获取网址.它还提供一个稍 ...

  5. 【leetcode】Reverse Nodes in k-Group (hard)☆

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...

  6. UVA 11827 Maximum GCD

    F - Maximum GCD Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Given the ...

  7. IOS - 首次启动程序出现的画面介绍

    1.在appdelegate.m中找到 “application:didFinishLaunchingWithOptions:” 通过NSUserDefaults 来进行判断 if (![[NSUse ...

  8. [Android Pro] Android以root起一个process[shell脚本的方法]

    reference to :  http://***/Article/11768 有时候我们写的app要用uid=0的方式启动一个process,framework层和app层是做不到的,只有通过写脚 ...

  9. [Android Pro] Android保存图片到系统图库

    http://stormzhang.github.io/android/2014/07/24/android-save-image-to-gallery/ http://blog.csdn.net/x ...

  10. 3ds max画曲线 设置摄像机的起始位置

    参考 http://www.3dmax8.com/3dmax/2013/0916/5661.html 如果想创建曲线段,可以在单击下一个点时按住鼠标不放,继续拖曳,再拖到另一个点上,单击鼠标右键,即可 ...