收藏 分销(赏)

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

上传人:pc****0 文档编号:7422884 上传时间:2025-01-03 格式:DOC 页数:4 大小:65.50KB 下载积分:10 金币
下载 相关 举报
Android ListView滑动过程中图片显示重复错位闪烁问题解决.doc_第1页
第1页 / 共4页
Android ListView滑动过程中图片显示重复错位闪烁问题解决.doc_第2页
第2页 / 共4页


点击查看更多>>
资源描述
http://www.mobiletrain.org/ 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。 更具体可见源代码ListView.obtainView。   这样,如下的getView写法就可以充分利用缓存大大提升ListView的性能。即便上万个行item,最多inflate的次数为n,n为一屏最多显示ListView行item的个数。 ListView Adapter getView写法 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @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(); } }   /** * ViewHolder * * @author trinea@ 2013-08-01 */ private static class ViewHolder {   ImageViewappIcon; TextView  appName; TextView  appInfo; } 这样提升了性能,但同时也会造成另外一些问题: a. 行item图片显示重复 这个显示重复是指当前行item显示了之前某行item的图片。 比如ListView滑动到第2行会异步加载某个图片,但是加载很慢,加载过程中listView已经滑动到了第14行,且滑动过程中该图片加载结束,第2行已不在屏幕内,根据上面介绍的缓存原理,第2行的view可能被第14行复用,这样我们看到的就是第14行显示了本该属于第2行的图片,造成显示重复。   b. 行item图片显示错乱 这个显示错乱是指某行item显示了不属于该行item的图片。 比如ListView滑动到第2行会异步加载某个图片,但是加载很慢,加载过程中listView已经滑动到了第14行,第2行已不在屏幕内,根据上面介绍的缓存原理,第2行的view可能被第14行复用,第14行显示了第2行的View,这时之前的图片加载结束,就会显示在第14行,造成错乱。   c. 行item图片显示闪烁 上面b的情况,第14行图片又很快加载结束,所以我们看到第14行先显示了第2行的图片,立马又显示了自己的图片进行覆盖造成闪烁错乱。   2、解决方法 通过上面的分析我们知道了出现错乱的原因是异步加载及对象被复用造成的,如果每次getView能给对象一个标识,在异步加载完成时比较标识与当前行item的标识是否一致,一致则显示,否则不做处理即可。 下面以使用ImageCache为ListView提供图片获取缓存为例,ListView中强烈推荐使用ImageCache。 首先在listview adapter的getView中添加 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @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(); }   …… // add tag for image, to compare it when image loaded finish imageView.setTag(imageUrl); // if not in cache, restore default if (!Cache.ICON_CACHE.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的onGetSuccess函数中添加 Java 1 2 3 4 5 6 7 8 9 10 11 public void onGetSuccess(String imageUrl, DrawableimageDrawable, View view, booleanisInCache) { // can be another view child, like textView and so on if (view != null &&imageDrawable != null) { ImageViewimageView = (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. 其他异步加载过程解决原理类似。 北京千锋互联科技有限公司 版权所有
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服