您的位置:首页 > 其它

ListView自定义适配器 优化

2016-11-01 17:05 148 查看
今天学习了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中,那么下一次继续使用就不需要再去寻找了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息