zoukankan      html  css  js  c++  java
  • 【移动开发】ViewPager缓存机制

    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

  • 相关阅读:
    【转】Android开发实践:自定义带消息循环(Looper)的工作线程
    【转】 解决IllegalStateException: Can not perform this action after onSaveInstanceState
    【转】Fresco之强大之余的痛楚
    【转】Android 防破解技术简介
    改进版本号的精确数据权限定义和实现
    明天是我的生日,写给24岁的自己
    javascrip cookie
    Servlet -- 跳转到页面后的绝对路径与相对路径的问题
    JAVA訪问URL
    跨浏览器resize事件分析
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6158021.html
Copyright © 2011-2022 走看看