ListView的一些优化

(1)利用convertview
  即,判断一下if (convertView == null) {}

  如:

public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
}
((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap((position & 1) == 1 ? mIcon1 :mIcon2);
return convertView;
}

但是,复用convertView对象时有时会出现图片错乱与listview中的文本不对应的情况,下面会具体说下。


(2)采用ViewHolder模式

    

  1.  public View getView(int position, View convertView, ViewGroup parent) {  
  2.         ViewHolder holder = null;  
  3.         if(convertView == null){  
  4.             holder = new ViewHolder();  
  5.               
  6.             convertView = mInflater.inflate(com.demo.listview.R.layout.list_item, null);  
  7.               
  8.             holder.title = (TextView) convertView.findViewById(com.demo.listview.R.id.title);  
  9.             holder.info =(TextView) convertView.findViewById(com.demo.listview.R.id.info);  
  10.             holder.image = (ImageView) convertView.findViewById(com.demo.listview.R.id.imageView);  
  11.               
  12.             convertView.setTag(holder);  
  13.               
  14.         }else{  
  15.             holder = (ViewHolder) convertView.getTag();  
  16.         }  
  17.             
  18.         holder.title.setText((String)lists.get(position).get("title"));  
  19.         holder.info.setText((String)lists.get(position).get("info"));  
  20.         holder.image.setBackgroundResource((Integer)lists.get(position).get("image"));  
  21.           
  22.         return convertView;  
  23.     }  
  24.       
  25.     public  class ViewHolder{  
  26.         public TextView title;  
  27.         public TextView info;  
  28.         public ImageView image;  
  29.     }  
  30.  

    使用这种模式省略了findViewById()这个操作。大家都知道,我们的视图其实是一个树状结构。那么findViewById其实就是一个遍历的过程,这肯定得花时间。
但是最后一种方法是把TextView和ImageView都放到了一个ViewHolder里面,这个ViewHolder对象又塞到了Item里面,这样,有了Item之后,直接把TextView和ImageView对象拿出来,速度就会有所提升。


(3)使用异步加载图片

     因为图片资源比较大,所以使用异步加载不会阻塞UI,增加用户体验。

(4) 快速滑动时不加载图片
(5) 如果自定义的item中有图片,需要处理图片(减少图片所占内存)

        1.对图片进行边界压缩

        2.用option类来保存图片大小

        3.避免图片的实时缩放,最好预先缩放到视图大小

(6)尽量避免在listview适配器中使用线程

  因为线程会造成内存泄露,而且线程的生命周期不可控。


这里就先介绍这几种优化方法,当然还有其他的方式,就靠兄弟们自己总结了。下面介绍下从服务器加载图片显示在listview中出现错乱或者闪烁的部分原因:

        刚刚我们提到了ListView条目的缓存机制,为了使我们的性能更好,就会复用convertView对象。我们在异步加载网络的图片的时候,可能由于下载的速度比较慢,就会出现图片闪烁,错乱的等问题。


a.图片错乱:某行条目显示了不是本条目的图片

       当进入在ListView页面的时候,会显示一屏的数据和图片,如果当时的网速的比较慢,异步加载第2个条目的图片,在图片加载的过程中,但是我们将ListView滑动到了第10个条目,根据ListView的缓存原理,第2个条目已经不在屏幕中了,那么第10个条目已经复用了第2个条目的的View对象了,这个时候图片加载完成了,那么第10个条目就出现本该是第2个条目的图片了。所以会出现图片与文本不匹配的情况。


b.图片闪烁

将a的情况修改下,如果第10个条目的图片又很快的加载完成了,就会替换之间复用的图片,这样就出现了闪烁的情况。

上面这两种情况在实际的项目中经常出现的,所以一定要弄清楚。原因我们已经知道了,就是因为复用了convertView,那么我们就该想一个办法来避免这种情况。

解决的办法:就是每次getView的时候给对象一个标识,在异步加载完成的时候比较标示和当前条目的标示是否一致,如果一致就显示图片,反之就不显示。具体的Demo可以自行搜索下。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值