1.    实现ViewPager的页面懒加载;
在某些情况下,例如使用ViewPager查看多张大图,此时多张图片不能一次性载入,只有在浏览该页面时才载入(或者预先载入下一页面)页面的具体内容。
2.    可控ViewPager缓存页面的数量。
常见的情况:1.页面的总数是已知的,或者可以计算出来,每个页面占用的资源并不多并且需要经常使用这些页面。这是可以考虑将其常驻ViewPager而不去销毁(频繁的销毁和重建也会消耗比较多的资源)。2.切换页面时默认情况下非相邻的页面会被销毁掉(ViewPager默认缓存或预加载相邻的页面以便快速切换),如果想要保持页面之前的状态,如滚动条滚动位置等比较困难;这是可以考虑将之前的页面缓存下来而不销毁掉。
ViewPager的默认加载与缓存模式
ViewPager和ListView、GridView等的数据加载方式类似,控件本身都提供了数据加载的适配器接口,程序员只需实现特定的Adapter就可以轻松的将数据填充到容器中。
我们来看一个简单的Demo

1.ViewPager懒加载和缓存测试类

  1. public class MainActivity extends Activity {
  2. private static final String TAG = "com.example.viewpagertest.MainActivity";
  3. private MyViewPager viewPager;
  4. private List<View> pagers = new ArrayList<View>();
  5. /** ViewPager缓存页面数目;当前页面的相邻N各页面都会被缓存 */
  6. private int cachePagers = 1;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. getViews();
  11. setContentView(viewPager);
  12. setListener();
  13. setAdapter();
  14. }
  15. private void getViews() {
  16. viewPager = new MyViewPager(this);
  17. for (int i = 0; i < 5; i++) {
  18. TextView textView = new TextView(this);
  19. pagers.add(textView);
  20. viewPager.onDisplay(i);//测试1
  21. }
  22. viewPager.setOffscreenPageLimit(cachePagers);// 设置缓存页面,当前页面的相邻N各页面都会被缓存
  23. }
  24. private void setAdapter() {
  25. viewPager.setAdapter(pagerAdapter);
  26. }
  27. private void setListener() {
  28. viewPager.setOnPageChangeListener(pageChangeListener);
  29. }
  30. /**
  31. * 页面数据适配器
  32. */
  33. private PagerAdapter pagerAdapter = new PagerAdapter() {
  34. @Override
  35. public void destroyItem(View container, int position, Object object) {
  36. Log.i(TAG, "destroyItem:" + position);
  37. ((ViewGroup) container).removeView((View) object);
  38. }
  39. @Override
  40. public void destroyItem(ViewGroup container, int position, Object object) {
  41. Log.i(TAG, "destroyItem:" + position);
  42. container.removeView((View) object);
  43. }
  44. @Override
  45. public Object instantiateItem(View container, int position) {
  46. Log.i(TAG, "instantiateItem:" + position);
  47. try {
  48. ((ViewPager) container).addView(pagers.get(position));
  49. // ((MyViewPager) container).onDisplay(position);//测试2
  50. } catch (Exception e) {
  51. Log.e(TAG, e.getMessage());
  52. }
  53. return pagers.get(position);
  54. }
  55. @Override
  56. public Object instantiateItem(ViewGroup container, int position) {
  57. Log.i(TAG, "instantiateItem:" + position);
  58. try {
  59. ((ViewPager) container).addView(pagers.get(position));
  60. // ((MyViewPager) container).onDisplay(position);//测试2
  61. } catch (Exception e) {
  62. Log.e(TAG, e.getMessage());
  63. }
  64. return pagers.get(position);
  65. }
  66. @Override
  67. public boolean isViewFromObject(View arg0, Object arg1) {
  68. return arg0 == arg1;
  69. }
  70. @Override
  71. public int getCount() {
  72. return pagers.size();
  73. }
  74. };
  75. /**
  76. * 页面滚动监听器
  77. */
  78. private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
  79. @Override
  80. public void onPageSelected(int arg0) {
  81. Log.i(TAG, "onPageSelected:" + arg0);
  82. // viewPager.onDisplay(arg0);//测试3
  83. }
  84. @Override
  85. public void onPageScrolled(int arg0, float arg1, int arg2) {
  86. }
  87. @Override
  88. public void onPageScrollStateChanged(int arg0) {
  89. }
  90. };
  91. /**
  92. * @Title setPageData
  93. * @Description 加载页面数据
  94. * @param position
  95. */
  96. private void setPageData(int position) {
  97. TextView textView = (TextView) pagers.get(position);
  98. textView.setText("pager" + position);
  99. Log.i(TAG, "setPageData position:" + position);
  100. }
  101. class MyViewPager extends ViewPager implements IPagerDisplay {
  102. public MyViewPager(Context context) {
  103. super(context);
  104. }
  105. public MyViewPager(Context context, AttributeSet attrs) {
  106. super(context, attrs);
  107. }
  108. @Override
  109. public void onDisplay(int position) {
  110. setPageData(position);
  111. }
  112. }
  113. }

2.ViewPager数据展示回调接口

  1. /**
  2. * @Title IPagerDisplay.java
  3. * @Package com.example.viewpagertest
  4. * @Description ViewPager数据展示回调
  5. * @author ze.chen
  6. * @date 2013-5-13 下午2:25:38
  7. * @version V1.0
  8. */
  9. package com.example.viewpagertest;
  10. /**
  11. * @ClassName IPagerDisplay
  12. * @Description ViewPager懒加载展接口;可以在PagerAdapter的instantiateItem时候调用,
  13. *              亦可以在OnPageChangeListener的onPageSelected时候调用
  14. *              ,两处的区别在于,instantiateItem方法ViewPager会自动缓冲
  15. *              (浏览pager1时将pager2的数据加载好),
  16. *              而onPageSelected则不会自动缓冲(浏览pager2时才加载pager2的数据)
  17. * @author ze.chen
  18. * @date 2013-5-13 下午2:25:38
  19. *
  20. */
  21. public interface IPagerDisplay {
  22. void onDisplay(int position);
  23. }

使ViewPager支持懒加载
在以上代码段中,分别注释了:测试1;测试2;测试3。
测试1:在加载ViewPager之前,初始化所有的页面和数据

  1. viewPager = new MyViewPager(this);
  2. for (int i = 0; i < 5; i++) {
  3. TextView textView = new TextView(this);
  4. pagers.add(textView);
  5. viewPager.onDisplay(i);//测试1
  6. }

对于测试2和测试3,只将控件添加到pagers列表中,数据不立刻加载
测试2:在ViewPager的页面实例化的时候加载数据,预加载的时候也会执行该方法。

  1. public Object instantiateItem(View container, int position) {
  2. Log.i(TAG, "instantiateItem:" + position);
  3. try {
  4. ((ViewPager) container).addView(pagers.get(position));
  5. ((MyViewPager) container).onDisplay(position);//测试2
  6. } catch (Exception e) {
  7. Log.e(TAG, e.getMessage());
  8. }
  9. return pagers.get(position);
  10. }

测试3:当该页面被选中的时候才加载该页面的数据,预加载页面时不会加载预加载页的数据。

  1. private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
  2. @Override
  3. public void onPageSelected(int arg0) {
  4. Log.i(TAG, "onPageSelected:" + arg0);
  5. viewPager.onDisplay(arg0);//测试3
  6. }
  7. ……

修改ViewPager的缓存页面数量

  1. viewPager.setOffscreenPageLimit(int numbers);

viewpager当前页面两侧缓存/预加载的页面数目。当页面切换时,当前页面相邻两侧的numbers页面不会被销毁。

参考资料

http://ranfeng0610.blog.163.com/blog/static/18570828420137206492642/

http://zilla.blog.51cto.com/3095640/1199366

http://blog.csdn.net/wangjinyu501/article/details/8169924

【移动开发】ViewPager缓存机制的更多相关文章

  1. H5 缓存机制浅析 移动端 Web 加载性能优化

    腾讯Bugly特约作者:贺辉超 1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5 引入的离线存储, ...

  2. ViewPager的缓存机制

    1.实现Viewpager的页面懒加载: 在某些情况下,例如使用ViewPager查看多张大图,此时多张图片不能一次性载入,只有在浏览该页面时才载入(或者预先载入下一页面)页面的具体内容. 2.可控V ...

  3. IOS - 开发之内存缓存机制

    使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行.有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求. 内存缓存我们可以使用sdk中的NSURLC ...

  4. iOS开发之内存缓存机制

    使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行.有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求. 内存缓存我们可以使用sdk中的NSURLC ...

  5. IOS开发缓存机制之—本地缓存机制

    功能需求 这个缓存机制满足下面这些功能. 1.可以将数据缓存到本地磁盘. 2.可以判断一个资源是否已经被缓存.如果已经被缓存,在请求相同的资源,先到本地磁盘搜索. 3.可以判断文件缓存什么时候过期.这 ...

  6. 【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qOMO0LIdA47j3RjhbCWUEQ 作者:李 ...

  7. JPA,EclipseLink 缓存机制学习(一) 树节点搜索问题引发的思考

    最近在项目在使用JPA+EclipseLink 的方式进行开发,其中EclipseLink使用版本为2.5.1.遇到一些缓存方面使用不当造成的问题,从本篇开始逐步学习EclipseLink的缓存机制. ...

  8. android WeakReference(弱引用 防止内存泄漏)与SoftReference(软引用 实现缓存机制(cache))

    在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...

  9. Http协议:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

    转载:http://mp.weixin.qq.com/s/uWPls0qrqJKHkHfNLmaenQ 导语 Http 缓存机制作为 web 性能优化的重要手段,对从事 Web 开发的小伙伴们来说是必 ...

随机推荐

  1. 【bzoj4571 scoi2016】美味

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...

  2. bzoj 2734: [HNOI2012]集合选数

    题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中. 同学们不喜 ...

  3. BZOJ4079 [Wf2014]Pachinko

    完整题面: 设f(i,j)表示路径经过(i,j)这个点的概率,列出方程消元. 但暴力消元的复杂度是$O((nm)^3)$,注意每一次消元只会影响前后m个方程,所以我们可以对于第i行,只存[i-m,i+ ...

  4. .net4.0设计模式(一)使用Lazy的单例模式

    延迟加载,亦称延迟实例化,延迟初始化等, 主要表达的思想是,把对象的创建将会延迟到使用时创建,而不是在对象实例化时创建对象,即用时才加载.这种方式有助于提高于应用程序的性能,避免浪费计算,节省内存的使 ...

  5. day4 liaoxuefeng--调试、线程、正则表达式

    一.错误.调试和测试 二.进程和线程 三.正则表达式

  6. glusterfs 4.0.1 rpc 分析笔记1

    Jimmy的文档:Glusterfs的rpc模块分析 第一节.rpc服务器端实现原理及代码分析 第二节.rpc客户端实现原理及代码分析 第三节.rpc通信过程分析 经过阅读源码对比之前提及的文档,我个 ...

  7. 吴恩达深度学习第1课第4周-任意层人工神经网络(Artificial Neural Network,即ANN)(向量化)手写推导过程(我觉得已经很详细了)

    学习了吴恩达老师深度学习工程师第一门课,受益匪浅,尤其是吴老师所用的符号系统,准确且易区分. 遵循吴老师的符号系统,我对任意层神经网络模型进行了详细的推导,形成笔记. 有人说推导任意层MLP很容易,我 ...

  8. mongoDB安装和启动

    安装: 1. mongodb(V3.4.7)安装包下载地址:https://www.mongodb.com/download-center#community 下载成功后直接运行,安装模式选择cust ...

  9. 用命令直接在两台ubuntu之间传输数据

    首先查看openssh-server是否启动: ps -e | grep ssh 如果没有任何提示则是没有启动: sudo /etc/init.d/ssh -start 启动进程.若提示找不到命令则需 ...

  10. beta 分布的详细介绍(转载)

    目前看到的关于beta分布最好的一个解释,由于贴过来格式不好看,所以附上链接: http://www.datalearner.com/blog/1051505532393058