概要
BaseAdapter是使用得比较多的一个类适配器,通过重写getView方法,展示自定义视图,如何优化getView方法是程序员讨论的热点,最近了看了一篇《ListView性能优化之视图缓存》的文章,使用ViewHolder类可以很好优化适配器的性能,原理:每次加载getView视图,只缓存第一次可见的getView视图,以后每次调用缓存,更新getView视图中数据达到优化性能目的。
方案一:
初学者经常使用的方法,方法中不使用ViewHolder缓存视图,首先初始化视图对象,每次执行getView方法,视图对象中的控件更新数据,代码如下:
- @Override
- public View getView(int position,View convertView,ViewGroup parent){
- if(convertView==null){//判断是否第一次加载
- convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);
- }
- //否则直接更新视图对象中数据
- ImageView mImageView=(ImageView)convertView.findViewById(R.id.icon);
- TextView mTextView=(TextView )convertView.findViewById(R.id.text);
- //设置数据
- mImageView.setImageResource(R.drawable.icon);
- mTextView.setText(R.string.text);
- return convertView;
- }
方案二:
使用ViewHolder,比较推荐的一种优化方案,在项目开发中,会在BaseAdapter子类中创建一个ViewHolder内部类,在ViewHolder类中声明控件名称,然后在getView方法中使用,该方法经过测试,在性能发面是最好的,代码如下:
- public class ViewHolder{
- //声明我们在getView中使用到的控件名称
- ImageView mImageView;
- TextView mTextView;
- }
- @Override
- public View getView(int position,View convertView,ViewGroup parent){
- ViewHolder mViewHolder;
- if(convertView==null){//判断是否第一次加载
- convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);
- //缓存第一次加载的视图控件
- mViewHolder=new ViewHolder();
- mViewHolde.mImageView=(ImageView)convertView.findViewById(R.id.icon);
- mViewHolde.mTextView=(TextView )convertView.findViewById(R.id.text);
- //存储标签
- convertView.setTag(mViewHolder);
- }else{
- //否则取出缓存中ViewHolder对象
- mViewHolder=convertView.getTag();
- }
- //更新视图对象中数据
- mViewHolder.mImageView.setImageResource(R.drawable.icon);
- mViewHolder.mTextView.setText(R.string.text);
- return convertView;
- }
方案三:
原理和方案二一样,在第一次加载可见视图的时候,缓存控件,以后每次加载直接更新数据,但多次使用findViewById方法,在性能上比第一种还差,不妨看试试,代码如下:
- @Override
- public View getView(int position,View convertView,ViewGroup parent){
- //判断是否第一次加载
- if(convertView==null){
- convertView=mInflater.inflate(R.layout_list_view_item_icon_text,null);
- //缓存第一次加载的视图控件,setTag第一个参数是存储的名称,第二个是控件
- convertView.setTag("icon", convertView.findViewById(R.id.icon));
- convertView.setTag("content", convertView.findViewById(R.id.text));
- }
- //否则直接更新视图对象中数据,从缓存中根据标签获取控件
- ImageView mImageView=(ImageView)convertView.getTag("icon");
- TextView mTextView=(TextView )convertView.getTag("content");
- //设置数据
- mImageView.setImageResource(R.drawable.icon);
- mTextView.setText(R.string.text);
- return convertView;
- }
总结:
三种方法中,现在性能上推荐使用ViewHolder,第一步定义内部类,第二步判断convertView是否为第一次加载,如果是第一次加载就初始化一次ViewHolder类,并设置ViewHolder属性值(声明的控件,作为内部类属性),否则根据标签中获取缓存的ViewHolder对象,再分别给ViewHolder属性设置值(即填充数据),这里需要注意是如果使用setTag有多个标签,使用带参数的setTag(mName,mView)的方法,例如方案三,有不明白的可以在线留言!
你可能感兴趣的文章
来源:TeachCourse,
每周一次,深入学习Android教程,关注(QQ158#9359$239或公众号TeachCourse)
转载请注明出处: https://www.teachcourse.cn/345.html ,谢谢支持!
转载请注明出处: https://www.teachcourse.cn/345.html ,谢谢支持!
分类:Android
标签:ViewHolder使用, View优化, 自定义View