浅谈扩展BaseAdapter的优化

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

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

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

@Override
public 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创建视图。一下时代码实现:

@Override
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值