开启固定模式的viewpager的复用模式+PagerAdapter浅解析
来源:互联网 发布:mac 推出键 编辑:程序博客网 时间:2024/06/05 02:06
现在android的adapterview几乎都要用到viewholder模式,然而viewpager几乎被人遗忘使用viewholder。
其实ViewPager的ViewHolder模式也并不是那么的难使用,但adapter重写的方法不同,这让我们看似无从下手!
public class ImagePagerAdapter extends PagerAdapter{ public ImageShowAdapter(Context pContext){ this.mContext = pContext; } @Override public void destroyItem(ViewGroup container, int position, Object object) {super.destoryItem(container,position,object) } @Override public int getCount() { return 0; } @Override public Object instantiateItem(ViewGroup container,final int position) { return super.instantiateItem(container,position); } @Override public boolean isViewFromObject(View view, Object object) { return super.isViewFromObject(view,object); }}
分析一下:
getCount()方法我们很熟悉,就是获取item的个数的;
destoryItem()方法用来移除视图;
instantiateItem()方法添加指定视图;
isViewFromobject()方法判断要添加的视图是否和pager的一个view相关联。做如此判断的原因是instantiateItem()方法返回的是一个object对象而不是view对象。具体原因可以查看源代码中对应的方法调用情况。
分析完基本的方法作用,我们还要分析一下一些更深层次的东西。
打印过日志后,我们发现instantiateItem()方法在2个以上的数据的时候会被执行两次。第一次初始化position=0的视图,第二次初始化下一张position=1的视图。
向左滑到第二个视图页初始化position=3的视图。再向左滑先移除position=0即第一个视图页,再初始化第三个视图页(position=4)。当连续向后滑动的时候始终会重复这一过程,如果当前页是第三页,则在viewpager的容器内最多保留三个视图,即第二页和第四页,第一页则在初始化第四页之前被remover掉。
如果我们中途使用viewpager.setCurrentItemPosition()也是一样的,先初始化当前页,然后初始化左相邻,再初始化右相邻。viewpager保证它的容器container中最多有三个视图。结果向后滑动就是先加入下一张视图,再移除非近邻视图,向前滑动先加入视图再销毁视图。针对这种机制,我们应该如何做和viewholder结合做到视图的复用,答案从被销毁的视图说起。
如代码示,我们需要创建一个缓存池:
LinkedList<View> mCaches = new LinkedList<View>();
因为container最多保存三个视图,所以每当有加入视图使container的子view个数超过三个,必然会移除不需要的视图。这个被移除的视图会携带对应的数据且不会被立马被内存内回收,所以复用已存在的对象,大大减少了我们的开销。
@Overridepublic Object instantiateItem(ViewGroup container,final int position) { View convertView = null; ViewHolder mHolder = null; if(mCaches.size() == 0){ convertView = LayoutInflater.from(mContext).inflat(R.xml.item); mHolder = new ViewHolder(); mHolder.imageView = (ImageView)convertView.findViewById(R.id.imageView); convertView.setTag(mHolder); }else{ convertView = (View)mCaches.removerFirst(); } mHolder.imageView.setImageResource(mImages.get()); return convertView;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); mCaches.add((View)object);}private class ViewHolder{ ImageView imageView;}
不过从这里可以看出,如果当向前滑动的时候因为执行方法的前后顺序不一致,所以切换滑动方向的次数越多,缓存内存的view越多,而且在向后切换到向前滑动的时候,则不会产生复用。前一个问题很好解决,后一个问题暂时还未得到解决方案。修改destroyItem方法如下:
@Overridepublic void destroyItem(ViewGroup container, int position, Object object) { if(mCache.size() > 0){ mCache.clear(); } container.removeView((View)object); mCaches.add((View)object);}到此,基本上缓存复用的代码已经全部完成。如果有更好的方案,欢迎留言讨论。另外附上一个非常酷炫轮播图库:
ViewPager轮播库
可以直接引用这个开源库中的ViewPagerEx,设置自己的adapter,达成简单的轮播图效果。也可以对控制器BaseSliderLayout进行修改,但是个人认为这种控制器的姿势略有错误,所以在内存开销上还是比较大,虽然达到了一定的开销时会自动回收。同时对于adapter的分析大体上也是和原生的ViewPager是一致的,只不过在初始化的时候会同时初始化左相邻,所以当数据为n的时候会按次序初始化0,n-1,1,另外当count为3的时候,每一次循环都看似没有需要销毁的地方。其实不是。这个库认为每一个循环都是独立的整体。所以不会认为当前需要被初始化的position(n-1)就是已经被初始化完成的position(n-1)。
eg:当前页是position1,已经初始化了position2,向前滑动,则还是先加入新的position2,再移除旧的position2。adapter始终忠实的执行着他的规则,不会因为size的改变而改变。
- 开启固定模式的viewpager的复用模式+PagerAdapter浅解析
- ViewPager的PagerAdapter的四个方法解析
- ViewPager的PagerAdapter.notifyDataSetChanged()
- ViewPager+PagerAdapter的使用
- ViewPager的适配器PagerAdapter
- [Widget]RecyclePagerAdapter-实现ViewPager复用回收的PagerAdapter
- ViewPager的PagerAdapter的介绍
- ViewPager的PagerAdapter的介绍
- ViewPager的PagerAdapter的封装
- ViewPager的PagerAdapter适配器使用
- ViewPager 放PagerAdapter 的notifyDataSetChanged()
- viewpager-----View作为ViewPager的数据源(PagerAdapter)
- Android--ViewPager的PagerAdapter的介绍
- ViewPager的使用,PagerAdapter的自定义改写
- 关于viewpager的适配器pageradapter的详解
- ViewPager的pageradapter加载视图的机制
- Android基础--ViewPager的PagerAdapter的介绍
- ViewPager的PagerAdapter不可以更新数据
- JavaScript设计模式 --- 方法的链式调用
- Ruby笔记
- 深入理解abstract class 和 interface
- curl命令
- 高德LBS使用以及注意事项+debug版本直接用release的签名配置
- 开启固定模式的viewpager的复用模式+PagerAdapter浅解析
- 接口类和抽象类的区别
- word 2010 标题行重复设置方法及表格标题行无法重复显示问题的解决方法
- Linux curses 总结二(对屏幕的操作)
- spring aop 2
- Codeforces Beta Round #87 (Div. 2 Only)深度优先
- TCP拥塞控制
- 安卓图表引擎AChartEngine(一) - 简介
- 给struts配置登陆验证过滤器,判断Session过期则重新登陆