Android Listview 滑动过程中提示图片重复错乱的原因及解决方法

所属分类: 软件编程 / Android 阅读数: 40
收藏 0 赞 0 分享

主要分析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 studio点击跳转WebView详解

这篇文章主要为大家详细介绍了Android studio点击跳转WebView的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android自定义Drawable实现圆形和圆角

这篇文章主要为大家详细介绍了Android自定义Drawable实现圆形和圆角,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android自定义水平渐变进度条

这篇文章主要为大家详细介绍了Android自定义水平渐变进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

ToolBar中menu无法同时显示图标和文字问题的解决方法

这篇文章主要为大家详细介绍了ToolBar中menu无法同时显示图标和文字问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解React Native监听Android回退按键与程序化退出应用

这篇文章主要介绍了详解React Native监听Android回退按键与程序化退出应用的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
收藏 0 赞 0 分享

android实现上传本地图片到网络功能

这篇文章主要为大家详细介绍了android实现上传本地图片到网络功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android实现QQ登录功能

这篇文章主要为大家详细介绍了Android实现QQ登录功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android实现简单的城市列表功能

这篇文章主要为大家详细介绍了Android实现简单的城市列表功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android Animation之TranslateAnimation(平移动画)

这篇文章主要为大家详细介绍了Animation之TranslateAnimation平移动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android 中Failed to read key from keystore解决办法

这篇文章主要介绍了Android 中Failed to read key from keystore解决办法的相关资料,希望通过本能帮助到大家,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多