浅谈ViewHolder的优化getView方法

2015-08-19 18:25 评论 0 条

概要

BaseAdapter是使用得比较多的一个类适配器,通过重写getView方法,展示自定义视图,如何优化getView方法是程序员讨论的热点,最近了看了一篇《ListView性能优化之视图缓存》的文章,使用ViewHolder类可以很好优化适配器的性能,原理:每次加载getView视图,只缓存第一次可见的getView视图,以后每次调用缓存,更新getView视图中数据达到优化性能目的。

方案一:

初学者经常使用的方法,方法中不使用ViewHolder缓存视图,首先初始化视图对象,每次执行getView方法,视图对象中的控件更新数据,代码如下:

  1. @Override  
  2. public View getView(int position,View convertView,ViewGroup parent){  
  3.   
  4.        if(convertView==null){//判断是否第一次加载  
  5.              convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);  
  6.        }  
  7.        //否则直接更新视图对象中数据  
  8.        ImageView mImageView=(ImageView)convertView.findViewById(R.id.icon);  
  9.        TextView mTextView=(TextView )convertView.findViewById(R.id.text);  
  10.         
  11.        //设置数据  
  12.        mImageView.setImageResource(R.drawable.icon);  
  13.        mTextView.setText(R.string.text);  
  14.         
  15.     return convertView;  
  16. }  

方案二:

使用ViewHolder,比较推荐的一种优化方案,在项目开发中,会在BaseAdapter子类中创建一个ViewHolder内部类,在ViewHolder类中声明控件名称,然后在getView方法中使用,该方法经过测试,在性能发面是最好的,代码如下:

  1. public class ViewHolder{  
  2.   
  3.         //声明我们在getView中使用到的控件名称  
  4.         ImageView mImageView;  
  5.         TextView mTextView;  
  6.    
  7. }  
  8.   
  9. @Override  
  10. public View getView(int position,View convertView,ViewGroup parent){  
  11.        ViewHolder mViewHolder;  
  12.   
  13.        if(convertView==null){//判断是否第一次加载  
  14.              convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);  
  15.                
  16.              //缓存第一次加载的视图控件  
  17.             mViewHolder=new ViewHolder();  
  18.             mViewHolde.mImageView=(ImageView)convertView.findViewById(R.id.icon);  
  19.             mViewHolde.mTextView=(TextView )convertView.findViewById(R.id.text);  
  20.               
  21.             //存储标签  
  22.             convertView.setTag(mViewHolder);  
  23.                
  24.        }else{  
  25.                
  26.              //否则取出缓存中ViewHolder对象  
  27.              mViewHolder=convertView.getTag();  
  28.                
  29.        }  
  30.       //更新视图对象中数据  
  31.       mViewHolder.mImageView.setImageResource(R.drawable.icon);  
  32.       mViewHolder.mTextView.setText(R.string.text);  
  33.         
  34.      return convertView;  
  35. }  

方案三:

原理和方案二一样,在第一次加载可见视图的时候,缓存控件,以后每次加载直接更新数据,但多次使用findViewById方法,在性能上比第一种还差,不妨看试试,代码如下:

  1. @Override  
  2. public View getView(int position,View convertView,ViewGroup parent){  
  3.       //判断是否第一次加载  
  4.        if(convertView==null){  
  5.   
  6.              convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);  
  7.              //缓存第一次加载的视图控件,setTag第一个参数是存储的名称,第二个是控件  
  8.              convertView.setTag("icon", convertView.findViewById(R.id.icon));  
  9.              convertView.setTag("content", convertView.findViewById(R.id.text));  
  10.               
  11.        }  
  12.           
  13.       //否则直接更新视图对象中数据,从缓存中根据标签获取控件  
  14.       ImageView mImageView=(ImageView)convertView.getTag("icon");  
  15.       TextView mTextView=(TextView )convertView.getTag("content");  
  16.         
  17.       //设置数据  
  18.       mImageView.setImageResource(R.drawable.icon);  
  19.       mTextView.setText(R.string.text);  
  20.         
  21.     return convertView;  
  22. }  

总结:

三种方法中,现在性能上推荐使用ViewHolder,第一步定义内部类,第二步判断convertView是否为第一次加载,如果是第一次加载就初始化一次ViewHolder类,并设置ViewHolder属性值(声明的控件,作为内部类属性),否则根据标签中获取缓存的ViewHolder对象,再分别给ViewHolder属性设置值(即填充数据),这里需要注意是如果使用setTag有多个标签,使用带参数的setTag(mName,mView)的方法,例如方案三,有不明白的可以在线留言!

当前文章价值1.95元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://www.teachcourse.cn/345.html ,谢谢支持!

资源分享

第一次使用Android Studio的感受 第一次使用Android Studio的感
python目录文件操作 python目录文件操作
Android学习笔记一:Java类加载过程 Android学习笔记一:Java类加载
Genymotion启动提示”Unable to start the virtual device“ Genymotion启动提示”Unable t

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情