AndroidListview 滑动过程中图片显示重复错乱解决方案

转载 2017年01月03日 14:04:32
主要分析Android中Listview滚动过程造成的图片显示重复、错乱、闪烁的原因及解决方法,顺便跟进Listview的缓存机制。
1、原因分析
Listview item 缓存机制:为了使得性能更优,Listview会缓存行item(某行对应的view)。listview通过adapter的getview函数获得每行的item。滑动过程中,
a、如果某行item已经划出屏幕,若该item不在缓存内,则put进缓存,否则更新缓存;
b、获取滑入屏幕的行item之前会先判断缓存中是否有可用的item,如果有,作为convertview参数传递给adapter的getview。
这样的话如下的getview写法就可以充分利用缓存大大提升listview的性能。即便上万个行item,最多inflate的次数为n,n为一屏最多显示listview行item的个数。
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.list_item,null);
holder = new ViewHolder();
....convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
}

这样提升了性能,但同时造成了一些问题。
a、行item图片显示重复
这个显示重复是指当前行item显示了之前某行item的图片
比如listview滑动到第二行会异步加载某个图片,但是加载很慢,加载过程中listview已经加载到15行,且滑动过程中该图片加载结束,第二行已经不再屏幕内,根据上面介绍的缓存原理,第二行的view可能被第14行服用,这样我们看到的就是14行显示了本该属于第二行的图片,造成重复。
b、行item图片显示错乱
这个显示错乱是指某行item显示了不属于该行item的图片。
比如listview滑动到第二行会异步加载某个图片,但是加载很慢,加载过程中listview已经滑动到14行,第二行已经不再屏幕内,根据上面介绍的缓存原理,第二行的view可能被第14行的复用,第十四行显示了第二行的view这时之前的图片加载结束,就会显示在第14行,造成混乱。
c、行item图品显示闪烁
上面b情况,14行图片又很快加载结束,所以我们看到第14行先显示了第二行的图片,马上又显示了自己的图片进行覆盖造成的闪烁错乱。
2、解决方法
通过上面的分析我们知道了出现错乱的原因是异步加载及对象被复用造成的,如果每次getview能给对象一个标识,在异步加载完成时比较标识与当前的item的标识是否是一致的,一致的则显示,否则不做处理即可。

代码中加上
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.list_item,null);
holder = new ViewHolder();
....convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}

。。。。。
imageview.setTag(imageurl);
if(!cache.icon_catch.get(imageurl,imageview){
imageview.setimageDrawable(null);
}
}

其中setTag表示设置标识,方便下面进行标志比对

1
if ( ! Cache . ICON_CACHE . get ( imageUrl , imageView ) )

Cache.ICON_CACHE为ImageCache的实例,表示如果不在缓存内则设置drawable为null(当然你可以可以设置为你自己的默认资源),防止显示了之前某个行item的图片,解决了a. 行item图片显示重复问题。

 

在ImageCache的OnImageCallbackListener的onImageLoaded函数中添加

Java
1
2
3
4
5
6
7
8
9
10
11
public void onImageLoaded ( String imageUrl , Drawable imageDrawable , View view , booleanisInCache ) {
     // can be another view child, like textView and so on
     if ( view != null && imageDrawable != null ) {
         ImageView imageView = ( ImageView ) view ;
         // add tag judge, avoid listView cache and so on
         String imageUrlTag = ( String ) imageView . getTag ( ) ;
         if ( ObjectUtils . isEquals ( imageUrlTag , imageUrl ) ) {
             imageView . setImageDrawable ( imageDrawable ) ;
         }
     }
} ;

在上面用String imageUrlTag = (String)imageView.getTag();取得之前设置的tag,然后和当前的url进行比较,如果相等则显示,解决了b. 行item图片显示错乱,c. 行item图片显示错乱的两个问题。其中ObjectUtils可见ObjectUtils@Github .

其他异步加载过程解决原理类似。


listView滑动时图片重复

在android开发中我们经常用到listView;listView的优点就不说了;下面我使用说说listView遇到问题;使用listView时,我传进来的list中对象,有的对象的图片属性有值,有...
  • luanshimingliu
  • luanshimingliu
  • 2015年05月19日 11:03
  • 276

android listview图片错位原理及解决方法

最近去面试被问到了listview中图片错位的原因,而我一直在往viewholder和tag机制上聊(被虐了),其实viewholder和tag机制只是解决图片错位的方法,而非产生图片错位的原理,回来...
  • a394268045
  • a394268045
  • 2016年02月23日 22:30
  • 6684

android - ListView优化机制及滑动时数据时出现的数据错乱重复问题

目录(?)[+] 该篇内容主要是记录我在实际开发中遇到的ListView滑动时数据错乱的几种情况,以及解决方法。在进行ListView滑动时数据错乱问题讨论之前会对ListView所谓的进行说明...
  • u012246458
  • u012246458
  • 2016年01月25日 20:41
  • 2976

Android Universal Image Loader加载 ListView 滑动过程中图片显示重复错位闪烁问题

项目使用uil加载listview图片时,出现过一次头像加载错了的问题, 之后在一篇博客上看到一种解决方案,可以借鉴 http://www.trinea.cn/android/android-list...
  • fumeidonga
  • fumeidonga
  • 2016年03月25日 15:39
  • 2778

Android ListView滑动过程中图片显示重复错乱闪烁问题解决

最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决   主要分析Android ListView滚动过程中图片显示重复、错乱、闪烁的原因及...
  • Lethe1989
  • Lethe1989
  • 2013年08月21日 21:31
  • 1398

ListView滑动过程中图片显示重复错乱闪烁问题解决

主要分析Android ListView滚动过程中图片显示重复、错乱、闪烁的原因及解决方法,顺带提及ListView的缓存机制。 1、原因分析 ListView item缓存机制:为了使得性能更优...
  • qiucheng1990
  • qiucheng1990
  • 2013年12月04日 10:46
  • 494

[转]Android ListView滑动过程中图片显示重复错乱闪烁问题解决

原文地址:http://www.oschina.net/question/221817_121051 主要分析Android ListView滚动过程中图片显示重复、错乱、闪烁的原因及解...
  • fzl562410663
  • fzl562410663
  • 2015年03月19日 20:17
  • 411

Imageloader 加载listview 头像 闪动,重复加载等问题的解决方案之一

android Imageloader 加载 listview 的时候,你的头像还在闪动么? 调研了一些方法,网上好多人都说给imgview.settag(),新手的我并不知道改之后处理,如果有大神,...
  • pppyaya123456789
  • pppyaya123456789
  • 2016年01月05日 13:07
  • 349

listview数据错乱、重复的原因分析与解决方案

目前我们使用listview展示数据时,adapter的getView方法通常使用convertView.setTag(viewHolder)的方式来避免出现卡顿的情况,这种方式能使convertVi...
  • whsdu929
  • whsdu929
  • 2016年09月21日 10:27
  • 1978

RecycleView的Item数据出现随机错乱重复问题解决

1.很奇葩的原因: 只是因为ViewHold的组件设置成了静态 2.把静态修饰去掉 去掉后数据正常显示 有静态修饰的时候...
  • tan6458
  • tan6458
  • 2015年10月05日 16:17
  • 2136
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AndroidListview 滑动过程中图片显示重复错乱解决方案
举报原因:
原因补充:

(最多只允许输入30个字)