浅谈扩展BaseAdapter的优化

来源:互联网 发布:c语言判断字母大小写 编辑:程序博客网 时间:2024/06/07 13:14

在开发Android应用的时候会常用到扩展的BaseAdapter来实例Adapter,通过getCount()方法来控制显示item的数量,用过getView()方法来返回每个item显示的数据的view。每显示一个item,getView()方法就会执行一次,因此getView()方法的执行效率十分关键,在显示的item十分庞大时,如果getView()方法执行速度慢,势必带来的问题就是手机滑动的十分的卡,用户体验十分的差。再以用户体验为重要指标的开发中,这种情况是不允许的,这就要求对getView()方法进行优化。

在扩展BaseAdapter的时候,如何解析出item对应的布局和找到相对应的控件是十分重要的。而找到item并在java代码中实例化的方法第一个想到的肯定就是View类的inflate()这个静态方法,但是这个方法实际上是十分消耗时间的。如果每次执行getView()方法都去执行这个方法,想想就知道是不可靠的。

那么如何解决这一麻烦呢,其实不用你自己费脑子想,API开发人员早就想到了这一问题。那么我们来看看他们是如何解决这一问题的吧:
我们再来看看getView()这个方法,它是这样的:

@Overridepublic View getView(int position, View convertView, ViewGroup parent){}

他有三个参数,存放item的convertView

posotion:当前item的位置position
convertView:存放item的View对象
parent:item的父容器

我们来重点看第二个参数converView,这就是解决上述inflate方法的精髓所在,上面已经说到inflate方法十分耗时,但它解析出来的对象对于每一个item都是相同的,也就是说每个item的布局都是一样的。从这点出发,能不能把item的布局的对象保存起来呢?convertView就是这样一个作用,下面是它的工作原理:

这里写图片描述

从图中可以看出一下几点信息:

1、只有可见的item存在于内存中
2、当有item滚出屏幕,并且有一个新的item滚上来(可见)时,convertView从null变为item1。

这种机制在生成视图时减少了大量的视图创建,省去了大量创建视图时的消耗。根据以上机制,在convertView不为空之后,就可以直接通过convertView创建视图。一下时代码实现:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    if(convertView == null){        convertView =View.inflate(context, R.layout.item, null);    }    ImageView imageView  =                 (ImageView)convertView.findViewById(R.id.item_iv);    imageView.setImageResource(R.drawable.ic_launcher);    return convertView;}

上面我们解决了一个inflate方法耗时的问题,其实还有一个方法也很耗时,那就是findViewById这个方法。同样的,每个item需要的控件都是来自于一个布局文件,也是相同的,这就诱使我们又想到了相同的方法——将找到的控件保存起来。如何保存呢,我们可以通过创建一个静态内部类ViewHolder来保存这几个控件,后面的item直接从ViewHolder中取出来使用就可以了。下面是完整的扩展BaseAdapter类MyAdapter的代码:

public class MyAdapter extends BaseAdapter{    private Context context;    private List<Bean> list;    public MyAdapter(Context context,List<Bean> list) {        this.context = context;        this.list = list;    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder viewHolder;        if(convertView==null){            viewHolder = new ViewHolder();            convertView = View.inflate(context, R.layout.item, null);            viewHolder.icon_iv =                     (ImageView) convertView.findViewById(R.id.item_iv);            viewHolder.name_tv =                     (TextView) convertView.findViewById(R.id.item_name);            viewHolder.desc_tv =                     (TextView) convertView.findViewById(R.id.item_desc);            convertView.setTag(viewHolder);        }else{            viewHolder = (ViewHolder) convertView.getTag();        }        viewHolder.desc_tv.setText(list.get(position).getDesc_tv());        viewHolder.icon_iv.setImageResource(list.get(position).getIcon_iv());        viewHolder.name_tv.setText(list.get(position).getName_tv());        return convertView;    }    static class ViewHolder{        ImageView icon_iv;        TextView name_tv;        TextView desc_tv;    }}
0 0
原创粉丝点击