ViewPager缓存机制

  1. 实现ViewPager的页面懒加载
    在某些情况下,例如使用ViewPager查看多张大图,此时多张图片不能一次性载入,只有在浏览该页面时才载入(或者预先载入下一页面)页面的具体内容。
  2. 可控ViewPager缓存页面的数量。
    常见的情况:1.页面的总数是已知的,或者可以计算出来,每个页面占用的资源并不多并且需要经常使用这些页面。这是可以考虑将其常驻ViewPager而不去销毁(频繁的销毁和重建也会消耗比较多的资源)。2.切换页面时默认情况下非相邻的页面会被销毁掉(ViewPager默认缓存或预加载相邻的页面以便快速切换),如果想要保持页面之前的状态,如滚动条滚动位置等比较困难;这是可以考虑将之前的页面缓存下来而不销毁掉。
    ViewPager的默认加载与缓存模式
    ViewPager和ListView、GridView等的数据加载方式类似,控件本身都提供了数据加载的适配器接口,程序员只需实现特定的Adapter就可以轻松的将数据填充到容器中。
    我们来看一个简单的Demo
    1.ViewPager懒加载和缓存测试类
    [java] view plaincopy在CODE上查看代码片派生到我的代码片
    public class MainActivity extends Activity {
    private static final String TAG = “com.example.viewpagertest.MainActivity”;
    private MyViewPager viewPager;
    private List pagers = new ArrayList();
    /* 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数据展示回调接口
[java] view plaincopy在CODE上查看代码片派生到我的代码片
/**
* @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之前,初始化所有的页面和数据
[java] view plaincopy在CODE上查看代码片派生到我的代码片
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的页面实例化的时候加载数据,预加载的时候也会执行该方法。
[java] view plaincopy在CODE上查看代码片派生到我的代码片
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:当该页面被选中的时候才加载该页面的数据,预加载页面时不会加载预加载页的数据。
[java] view plaincopy在CODE上查看代码片派生到我的代码片
private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.i(TAG, “onPageSelected:” + arg0);
viewPager.onDisplay(arg0);//测试3
}
……

修改ViewPager的缓存页面数量
[java] view plaincopy在CODE上查看代码片派生到我的代码片
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值