Android Listview 滑动过程中提示图片重复错乱的原因及解决方法
主要分析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表示设置标识,方便下面进行标志比对
if ( ! Cache . ICON_CACHE . get ( imageUrl , imageView ) )
Cache.ICON_CACHE为ImageCache的实例,表示如果不在缓存内则设置drawable为null(当然你可以可以设置为你自己的默认资源),防止显示了之前某个行item的图片,解决了a. 行item图片显示重复问题。
在ImageCache的OnImageCallbackListener的onImageLoaded函数中添加
Java
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 .
其他异步加载过程解决原理类似。
以上所述是小编给大家介绍的Android Listview 滑动过程中提示图片重复错乱的原因及解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
- Android下拉刷新ListView——RTPullListView(demo)
- android开发教程之实现listview下拉刷新和上拉刷新效果
- Android实现上拉加载更多以及下拉刷新功能(ListView)
- android下拉刷新ListView的介绍和实现代码
- Android ListView实现上拉加载更多和下拉刷新功能
- Android ListView下拉刷新上拉自动加载更多DEMO示例
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
- Android实现Listview异步加载网络图片并动态更新的方法
- 安卓(Android)ListView 显示图片文字
- Android ListView实现下拉顶部图片变大效果
相关文章
Android TextView使用SpannableString设置复合文本的方法详解
这篇文章主要介绍了Android TextView使用SpannableString设置复合文本的方法,结合实例形式详细分析了Android中SpannableString类的功能及相关用法,需要的朋友可以参考下2016-08-08android TextView中识别多个url并分别点击跳转方法详解
在本篇文章里小编给大家整理的是关于android TextView中识别多个url并分别点击跳转方法详解,需要的朋友们可以学习参考下。2019-08-08Android仿微信列表滑动删除 如何实现滑动列表SwipeListView
这篇文章主要为大家详细介绍了Android仿微信列表滑动删除,如何实现滑动列表SwipeListView,感兴趣的小伙伴们可以参考一下2016-08-08
最新评论