ViewPager页面懒加载与缓存页面数量可控

ViewPager页面懒加载与缓存页面数量可控


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

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

2.ViewPager数据展示回调接口

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

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

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

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

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

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

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

修改ViewPager的缓存页面数量

1
viewPager.setOffscreenPageLimit( int  numbers);

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值