Day11、ListView的二级优化

在一级优化中我们只是对行布局进行了优化,在此基础上,我们还需要对控件的获取进行优化,即减少4000的次数,因此需要自定义一个ViewHolder类来针对行布局中的控件获取,来优化它。

一、使用ViewHolder进行优化

1.MyAdapter.java代码如下。
package com.oldtogether.adapterdemo2;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter3 extends BaseAdapter {
    List<Map<String, Object>> list;
    LayoutInflater Inflater;// 反射器

    // 初始化反射器
    public MyAdapter3(Context context) {
        this.Inflater = LayoutInflater.from(context);
    }

    public void setList(List<Map<String, Object>> list) {
        this.list = list;
    }

    @Override
    public int getCount() {
        // 获取ListView的行数
        return list.size();
    }

    @Override
    public Object getItem(int index) {
        // 获得Item项的对象,其中的参数为此Item的下标,从零开始
        return list.get(index);
    }

    @Override
    public long getItemId(int id) {
        // 获得ItemId
        return id;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder=null;
        //判断convertView是否为空,其来自getView方法的形参
        if (convertView == null) {
            //通过反射获得行布局对象
            convertView = Inflater.inflate(R.layout.item, null);
            holder=new ViewHolder();
            // 获得控件对象,并作为ViewHolder的属性
            holder.logo = (ImageView) convertView.findViewById(R.id.iv_logo);
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.version = (TextView) convertView.findViewById(R.id.version);
            holder.size = (TextView) convertView.findViewById(R.id.size);
            //将ViewHolder和convertView关联起来
            convertView.setTag(holder);
        }else{
            holder=(ViewHolder) convertView.getTag();
        }

        // 添加数据,注意需要强转
        Map map = list.get(position);
        holder.logo.setImageResource((int) map.get("logo"));
        holder.title.setText((String) map.get("title"));
        holder.version.setText((String) map.get("version"));
        holder.size.setText((String) map.get("size"));

        return convertView;
    }

    //自定义的ViewHolder类
    public class ViewHolder{
        ImageView logo;
        TextView title;
        TextView version;
        TextView size;
    }
}
2.实现代码的步骤

1.在MyAdapter中声明一个自定义的ViewHolder类,将控件属性设置为成员属性。
2.用if…else语句,将行布局和控件关联在一起,作为一个整体框架。
3.填充数据,就像填空题那样,将将资源加载到holder中。

二、ViewHolder的工作原理

1.注解和帮助记忆思维草图如下

这里写图片描述

2.通过自定义的ViewHolder类,将属性抽象封装在一起;再通过一个if…else语句将item项和所有控件地址绑(convertView.setTag(holder);)在一起,形成一个模块;最后将需要的具体数据资源set到上面即可。
3.到底优化了没有?答案是肯定的,上面所示的草图中(假设一屏幕显示4行,每行中只要4个控件),通过inflate来反射的行布局只是调用了5次,通过findViewById来反射的控件对象仅4*5=20次,显然如果有成千上万行ListView,显然刷屏速度和各方面都提高了。

三、心得总结

1.优化的实质是,item和item中控件具体的位置,即获得一个没有内容的行布局框架,内容还需要自己填写;
2.巧用setTag()和getTag()方法,其所接受的数据类型是Object,因此在get时需要强转;
3.总之,ViewHolder是一个自定义的类,它存储了通过findViewByID获取的控件对象;当convertView被新建时,ViewHolder也随之缓存到Recycle中;当convertView被重新利用是,ViewHolder也被随之取出,从而直接给各个控件赋值,无需再次调用findByViewId方法;
4.学完了这几节,需要写更多代码来加强记忆。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值