不知道你们使用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. FindinFiles - Windows文件内查找插件

    FindInFiles for Windows 今天分享一个不错的插件工具:FindInFiles.如其名,其功能和Visual Studio的Ctrl+H快捷键类似,方便Windows使用者在资源管 ...

  2. 【leetcode】 Permutation Sequence (middle)

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  3. 【编程题目】输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数, 使其和等于 m ... ★

    第 21 题(数组)2010 年中兴面试题编程求解:输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来. 我的思路: 从小 ...

  4. 未将对象引用设置到对象的实例 启用 JIT 调试后,任何无法处理的异常

    严谨!!!! DataSet ds = salarySum.GetDataSalarySum2(libUser.SelectedValue, dtpMonth.Value.Date);         ...

  5. JS 保留两位小数问题收集

    1.使用四舍五入的方法,保留小数点后的两位小数: toFixed里面的参数表示保留的小数的位数,范围是0-20,超过20位就会报错了 <script> var num=22.127456; ...

  6. 生成Geometry

    // 由一组点集生成一张三角面片网格Geometry osg::Geometry* createTRIANGLESGeometry(MyMesh &mesh) { osg::ref_ptr&l ...

  7. Alcatraz安装在xcode7失败执行下面代码

    1.步奏rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/Alcatraz.xcplugin 2.步奏 rm ...

  8. hdu 5585 Numbers

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 思路:对于2和5只须看最后一位数,对于三看所有位的数字之和就行 #include<stdi ...

  9. 三、jQuery--Ajax基础--Ajax全接触--扩展知识(跨域)

  10. drozer unknown module处理办法

    将目录切换到drozer安装目录,然后在执行: