android中ListView异步加载图片时的图片错位问题解决方案-阿里云开发者社区

开发者社区> 再见孙悟空_> 正文

android中ListView异步加载图片时的图片错位问题解决方案

简介: android中ListView异步加载图片时的图片错位问题解决方案
+关注继续查看

Android中的ListView是一个非常常用的控件,但是它却并不像想象中的那么简单。特别是当你需要在ListView中展示大量网络图片的时候,处理不好轻则用户体验不佳,重则OOM,异步线程丢失或者图片错位。

关于其中的OOM和异步线程丢失的问题,是一个很庞大的话题,本人能力有限,无法说清,只有遇到的时候临时找原因,想办法解决了。但是对于图片错位,却是可以避免的,今天我们就来说一说ListView异步加载图片中的图片错位问题。

为什么会出现图片错位的问题呢?一般是重用了convertView导致的。如果你重用了convertView,此时convertView中的ImageView的id值是相等的,而我们在设置ImageView的图片时,是根据id来设置的,此时就出现了图片错位问题。这里童鞋们可以自己去测试一下,不重用convertView,也就是每次getView的时候,都使用findViewById(R.id.xx)去得到每一个Item的ImageView,异步下载图片的方法也只是简单的开一个AsyncTask执行下载。在这种情况下,图片一般是不会产生错位的。原因很简单,认真读一读前面的内容就明白了。但是你如果真的在使用这种方法来使用getView的话,并且图片量比较大的时候,你程序的性能肯定不会好到哪里去了。因此,重用convertView还是很有必要的。

这里需要注意,convertView是否为null会根据ListView的中布局标签值的不同有区别,具体的内容请参见这两篇文章:

android listview 连续调用 getview问题分析及解决

[Android] ListView中getView的原理+如何在ListView中放置多个item

这也就是说,某种情况下你界面中的第一张和第二张图片之间就有可能产生错位,因为有可能第二个可见的ImageView就来自共用的convertView。

处理像这种图片的异步加载的问题,我们的一般思路是:下载的图片根据图片名称存入到SDCard中,最新加载的图片存入到软引用中。我们在getView中给ImageView设置图片的时候,首先根据url,从软引用中读取图片数据;如果软引用中没用,则根据url(对应图片名)从SDCard中读取图片数据;如果SDCard中也没有,则从网络上下载图片,在图片下载完成后,回调主线中的方法更新ImageView。下面我们就照着上面的思路,先把程序整出来再说吧。先看下效果图:

布局文件有两个,很简单,一个表示ListView(main.xml),一个表示ListView中的元素(single_data.xml),如下:

[java] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:orientation="vertical"  
  7.     android:background="@android:color/darker_gray"  
  8.     tools:context=".MainActivity" >  
  9.   
  10.     <ListView  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="wrap_content"  
  13.         android:cacheColorHint="@null"  
  14.         android:id="@+id/listview"  
  15.          />  
  16.   
  17. </LinearLayout>  

 

[java] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@android:color/white"  
  6.      >  
  7.     <ImageView   
  8.         android:layout_width="150dp"  
  9.         android:layout_height="150dp"  
  10.         android:scaleType="fitXY"  
  11.         android:id="@+id/image_view"  
  12.         android:background="@drawable/ic_launcher"  
  13.         />  
  14.     <TextView   
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_alignTop="@id/image_view"  
  18.         android:layout_alignBottom="@id/image_view"  

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
ubuntu 64位android项目报错的解决方案,打开64位 Ubuntu 的32位支持功能
ubuntu的64位下的android环境,说实话,还真得费点精力了,解决一个问题,又出来一个新问题。 小编昨天刚好不容易将android的环境搭建好了,这不,刚建了个项目,直接就报错,下面是罗列出的几条: 1.
827 0
android用eclipse开发碰到65535问题的完美解决方案
android用eclipse开发碰到65535问题的完美解决方案
3 0
关于wordpress主题、插件上传和下载问题及其上传图片权限问题解决方案
主题官方下载地址:https://wordpress.org/themes/ 插件官方下载地址: https://wordpress.org/plugins/ 主题的上传下载,无疑是需要ftp服务器的。
1882 0
Android viewpager 嵌套 viewpager滑动 点击事件冲突解决方案
为了解决这个问题。可以自定义viewpager,然后在里面监听首饰,自定义点击事件   package com.hpuvoice.view; import android.content.
832 0
解决Linux无法打开android模拟器问题
笔者最近重新安装了系统(deepin),但随之带来了一个问题,就是无法创建Android模拟器。其实这个问题我倒是在之前遇到过2次,很好解决,删除'yourPath'/Sdk/emulator/lib64/libstdc++.so就行了。
1050 0
246
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载