老师那个解决错位的办法好像有问题
上述出现的错位问题是这样的: 显示的某一个列表项,左边图片和右边文字不匹配,但过一会。就会显示正确匹配了。出现原因就是ListView的缓存机制,在作怪。ListView缓存机制 我们在加载图片的时候有一个下载的时间
问题,这样convertview 实际上已经返回了,而它所需的图片资源可能还在下载中,这样的话 文字是当前的文字,而图片呢?就是加载之前convertview里面的图片,因此图片错位是避免不了的了。因此我觉得老师那个解决错位的办法好像 不太对。
上述出现的错位问题是这样的: 显示的某一个列表项,左边图片和右边文字不匹配,但过一会。就会显示正确匹配了。出现原因就是ListView的缓存机制,在作怪。ListView缓存机制 我们在加载图片的时候有一个下载的时间
问题,这样convertview 实际上已经返回了,而它所需的图片资源可能还在下载中,这样的话 文字是当前的文字,而图片呢?就是加载之前convertview里面的图片,因此图片错位是避免不了的了。因此我觉得老师那个解决错位的办法好像 不太对。
2015-06-01
你其实没明白。
listView convertView缓存机制 & 异步加载图片 问题剖析
先介绍下listView的convertView缓存机制 & 异步加载图片:
convertView缓存机制:我们假设一个屏幕一次显示8个item,当第9个item划进屏幕时,ListView对adapter说,返给我一个view,我要显示。adapter调用getView()方法,由于使用了convertView缓存机制,getView(),会在上一次new 出来的8个itemview中取出第一个itemview(这时因为不显示了,listview将其变成了convertview),并给了listview作为第9个item的view。
异步加载图片:如果我们不适用异步加载图片,那么必须要在每次getview()返回一个view前把view的iamgeview设置好了图片再返回给Listview,这意味着我必须等网络下载好了这个图片我才能返回给listview一个item,很明显,下滑效果是屏幕卡顿的半天没反应。但是使用异步加载,先让adapter返回一个view,view的iamgeview我先不确定,并开启一个新线程去下载图片,等图片下载好了,再去更新到这个view的imageview。当然了,一般只需要异步加载图片,而文字信息默认认为已经取得了,当然文字也是可以异步加载的。
但是,当我们使用了listView在通过 convertView缓存机制 & 异步加载图片时,若快速滑动屏幕,会发生图片闪顿2次以上的错图最后才能正确显示图片的现象。我们来剖析原因:
之所以会在下滑后,图片显示出一个之前的错图,是因为convertview的缓存,这个convertview的图片还是保持着上一次的图片,然而我这里的新线程还没来得及下载好并更新到这个imageview,你的老图片就已经显示上去了。所以造成了第一次的错图。但是这里不会出现闪!
然后快速下滑,发现第一个错图就要被正确的第二张图显示替换时,我又把屏幕下滑了,所以我又换了个图,第二次又错图了。我假设每个图片下载需要1s,由于我使每个异步线程人工阻塞了1s,那么上来有8个异步线程在运行(编号1-8),如果1s之内下滑了ListView比如说下滑了8个,那么新更新的8个item还是用的以前老view(不是新new出来的),并且又开启了8个异步线程(编号9-16)。因为之前显示了是老的图片。然后1-8号异步线程运行完毕,更新ImageView,所以出现了一次闪,紧跟着9-16异步线程运行完毕,又更新imageView,又出现了一次闪。最终显示正确结果。这就是下滑时先显示默认图片,再闪一下错误图片,最后闪一下正确图片的本质过程。这次是另一种错误原因。
所以,我们为了解决问题,分两步走:
1,在getview返回一个convertView之前,我把imageview设置为一个固定的图片(ic_launcher),覆盖掉convertview的老错图,这样就不会在显示时造成错图尴尬了。所以convertView缓存机制造成的错图原因得到解决,因为: 缓存造成的错图是无法避过的········
2.在把imageview设置为一个固定的图片(ic_launcher),覆盖掉convertview的老错图之后,我为ImageView设置了一个tag(url),tag里放的是一个唯一标识url,并且在异步线程里传入url,当线程下载好了后,先判断iamgeview的tag是不是我下载的这个url,如果是,说明主人还没有滑动,还在等我加载图片,那么我赶紧显示上去;如果tag!=url了,说明主人早已又滑了一段,我所在的convertView又被替换了一次,所以我还是别显示了!
举报