ListView自定义适配器 优化

今天学习了list的自定义适配器,本以为能够把view以及对应的数据全都存放在listview就万事大吉了,但是没考虑到一点,那就是内存的使用问题,当我们使用getview不停得加载listview中数据时,有一段代码是不断重复执行的,那就是我们对应的搜索空间的代码

public View getView(int position, View convertView, ViewGroup parent) {
 
        convertView= LayoutInflater.from(context).inflate(R.layout.listview,null);
  
        textdate=(TextView) convertView.findViewById(R.id.textdate);
        texttitle= (TextView) convertView.findViewById(R.id.texttitle);
        textmain= (TextView) convertView.findViewById(R.id.textmain);
        textid= (TextView) convertView.findViewById(R.id.text_id);


    textdate.setText(infos.get(position).getYear()+"-"+infos.get(position).getMonth()+"-"+infos.get(position).getDay());
    texttitle.setText(infos.get(position).getTitle());
    textmain.setText(infos.get(position).getMain());
    textid.setText(Integer.toString(infos.get(position).getId()));
    return convertView;

}
当我们使用convertview来进行自定义布局时,我们有一点是不知道的,听我慢慢讲解:

假顶我们的手机屏幕高度为100,listview中的item高度为10,

那么我们的手机屏幕最多能够同时容纳10个item,而当第1次打开activity的时候,系统自动加载了1-10 的item进去

        textdate=(TextView) convertView.findViewById(R.id.textdate);
        texttitle= (TextView) convertView.findViewById(R.id.texttitle);
        textmain= (TextView) convertView.findViewById(R.id.textmain);
        textid= (TextView) convertView.findViewById(R.id.text_id);
那么,对于搜寻控件的代码来说,是不是至少执行了10次?

因为每一个item创建的时候,都会执行一次。


OK那么当我们滑动屏幕,第11个view加载进来进来的时候,第一个view有一半超出屏幕上方,只有下半部分还留在屏幕内


这个图片只是例子,大家可以看到,屏幕最上面的数字1,还有半个在屏幕内,屏幕最底部,42有半个进入屏幕,但是还没有完全进入屏幕,那么这个时候,承载42的view也是系统新创建的,

那么当1完全退出屏幕,而42完全进去以后,承载1的concertview就会空出来,他会跑到屏幕最下面,去做承载43的容器,即把view里面的内容从1换成43然后又从屏幕底部露出来,这样节省了再次为43重启搜索一次控件的开销。

当然当item数量少的时候,这样做效果不明显,但是如果当item数量有1万条的时候呢,那么我们就可以节约1万次通过findviewbyid来查找控件,运行效率就大大增加了。

那么是如何实现的呢:

其实就是定义了一个静态内部类 viewholder,将搜索到的view全部存到这个类当中,因为是静态的,那么可以跟类一起保存下来,不用多次寻找

static class ViewHodler{
    TextView texttitle,textdate,textmain,textid;
}

其实单独看这个还是看不出什么问题,那么我放出整段的代码

 public View getView(int position, View convertView, ViewGroup parent) {
        ViewHodler vh;
        if(convertView==null){
            convertView= LayoutInflater.from(context).inflate(R.layout.listview,null);
            vh=new ViewHodler();
            vh.textdate=(TextView) convertView.findViewById(R.id.textdate);
            vh.texttitle= (TextView) convertView.findViewById(R.id.texttitle);
            vh.textmain= (TextView) convertView.findViewById(R.id.textmain);
            vh.textid= (TextView) convertView.findViewById(R.id.text_id);
            convertView.setTag(vh);
        }else{
            vh= (ViewHodler) convertView.getTag();
        }



        vh.textdate.setText(infos.get(position).getYear()+"-"+infos.get(position).getMonth()+"-"+infos.get(position).getDay());
        vh.texttitle.setText(infos.get(position).getTitle());
        vh.textmain.setText(infos.get(position).getMain());
        vh.textid.setText(Integer.toString(infos.get(position).getId()));
        return convertView;

    }
    static class ViewHodler{
        TextView texttitle,textdate,textmain,textid;
    }
}
这是整体的代码,

主要是通过

 convertView.setTag(vh);

来实现将vh对象存储起来,方便我们下次使用,当我们第一次创建view的时候,搜索控件,然后就把搜索的结果存到了静态的viewholder中,那么下一次继续使用就不需要再去寻找了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值