ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码:

  1. package cn.wangmeng.test;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.lang.ref.SoftReference;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import java.util.HashMap;
  8. import android.graphics.drawable.Drawable;
  9. import android.os.Handler;
  10. import android.os.Message;
  11. public class AsyncImageLoader {
  12. private HashMap<String, SoftReference<Drawable>> imageCache;
  13. public AsyncImageLoader() {
  14. imageCache = new HashMap<String, SoftReference<Drawable>>();
  15. }
  16. public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
  17. if (imageCache.containsKey(imageUrl)) {
  18. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  19. Drawable drawable = softReference.get();
  20. if (drawable != null) {
  21. return drawable;
  22. }
  23. }
  24. final Handler handler = new Handler() {
  25. public void handleMessage(Message message) {
  26. imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
  27. }
  28. };
  29. new Thread() {
  30. @Override
  31. public void run() {
  32. Drawable drawable = loadImageFromUrl(imageUrl);
  33. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
  34. Message message = handler.obtainMessage(0, drawable);
  35. handler.sendMessage(message);
  36. }
  37. }.start();
  38. return null;
  39. }
  40. public static Drawable loadImageFromUrl(String url) {
  41. URL m;
  42. InputStream i = null;
  43. try {
  44. m = new URL(url);
  45. i = (InputStream) m.getContent();
  46. } catch (MalformedURLException e1) {
  47. e1.printStackTrace();
  48. } catch (IOException e) {
  49. e.printStackTrace();
  50. }
  51. Drawable d = Drawable.createFromStream(i, "src");
  52. return d;
  53. }
  54. public interface ImageCallback {
  55. public void imageLoaded(Drawable imageDrawable, String imageUrl);
  56. }
  57. }

以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。 
几个辅助类文件:

  1. package cn.wangmeng.test;
  2. public class ImageAndText {
  3. private String imageUrl;
  4. private String text;
  5. public ImageAndText(String imageUrl, String text) {
  6. this.imageUrl = imageUrl;
  7. this.text = text;
  8. }
  9. public String getImageUrl() {
  10. return imageUrl;
  11. }
  12. public String getText() {
  13. return text;
  14. }
  15. }
  1. package cn.wangmeng.test;
  2. import android.view.View;
  3. import android.widget.ImageView;
  4. import android.widget.TextView;
  5. public class ViewCache {
  6. private View baseView;
  7. private TextView textView;
  8. private ImageView imageView;
  9. public ViewCache(View baseView) {
  10. this.baseView = baseView;
  11. }
  12. public TextView getTextView() {
  13. if (textView == null) {
  14. textView = (TextView) baseView.findViewById(R.id.text);
  15. }
  16. return textView;
  17. }
  18. public ImageView getImageView() {
  19. if (imageView == null) {
  20. imageView = (ImageView) baseView.findViewById(R.id.image);
  21. }
  22. return imageView;
  23. }
  24. }

ViewCache是辅助获取adapter的子元素布局

  1. package cn.wangmeng.test;
  2. import java.util.List;
  3. import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
  4. import android.app.Activity;
  5. import android.graphics.drawable.Drawable;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.ViewGroup;
  9. import android.widget.ArrayAdapter;
  10. import android.widget.ImageView;
  11. import android.widget.ListView;
  12. import android.widget.TextView;
  13. public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
  14. private ListView listView;
  15. private AsyncImageLoader asyncImageLoader;
  16. public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
  17. super(activity, 0, imageAndTexts);
  18. this.listView = listView;
  19. asyncImageLoader = new AsyncImageLoader();
  20. }
  21. public View getView(int position, View convertView, ViewGroup parent) {
  22. Activity activity = (Activity) getContext();
  23. // Inflate the views from XML
  24. View rowView = convertView;
  25. ViewCache viewCache;
  26. if (rowView == null) {
  27. LayoutInflater inflater = activity.getLayoutInflater();
  28. rowView = inflater.inflate(R.layout.image_and_text_row, null);
  29. viewCache = new ViewCache(rowView);
  30. rowView.setTag(viewCache);
  31. } else {
  32. viewCache = (ViewCache) rowView.getTag();
  33. }
  34. ImageAndText imageAndText = getItem(position);
  35. // Load the image and set it on the ImageView
  36. String imageUrl = imageAndText.getImageUrl();
  37. ImageView imageView = viewCache.getImageView();
  38. imageView.setTag(imageUrl);
  39. Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
  40. public void imageLoaded(Drawable imageDrawable, String imageUrl) {
  41. ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
  42. if (imageViewByTag != null) {
  43. imageViewByTag.setImageDrawable(imageDrawable);
  44. }
  45. }
  46. });
  47. if (cachedImage == null) {
  48. imageView.setImageResource(R.drawable.default_image);
  49. }else{
  50. imageView.setImageDrawable(cachedImage);
  51. }
  52. // Set the text on the TextView
  53. TextView textView = viewCache.getTextView();
  54. textView.setText(imageAndText.getText());
  55. return rowView;
  56. }
  57. }

ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。 
最后贴出布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="horizontal"
  4. android:layout_width="fill_parent"
  5. android:layout_height="wrap_content">
  6. <ImageView android:id="@+id/image"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. />
  10. <TextView android:id="@+id/text"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"/>
  13. </LinearLayout>

原文地址:http://blog.jteam.nl/2009/09/17/exploring-the-world-of-android-part-2

ListView异步加载图片的更多相关文章

  1. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  2. ListView异步加载图片,完美实现图文混排

    昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...

  3. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  4. Android 实现ListView异步加载图片

    ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码: package cn.wangmeng.test; ...

  5. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  6. Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法

    Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...

  7. listview异步加载图片并防止错位

    android listview 异步加载图片并防止错位 网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 conver ...

  8. Listview 异步加载图片之优化篇(有图有码有解释)

    在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...

  9. Android之ListView异步加载图片且仅显示可见子项中的图片

    折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整 ...

随机推荐

  1. Postman前端HTTP请求调试神器教程

    Postman功能: 主要用于模拟网络请求包 快速创建请求 回放.管理请求 快速设置网络代理 我们看下界面: 一 接口请求流程: 二 postman使用   从流程图中我们可以看出,一个接口请求需要设 ...

  2. 阿里最新出的图书《码出高效:Java开发手册》宣传手册图片里出了比较搞笑的错误,大家没有发现?

  3. (13)oracle导出、导入

        导出 导出分三种 导出表.导出方案(用户).导出数据库 导入导出不需要进入sqlplus,都需要从cmd进到所安装的oracle目录的bin文件夹下 例如:D:\app\Administrat ...

  4. Codeforces Round #428 A. Arya and Bran【模拟】

    A. Arya and Bran time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  5. Codeforces 954I Yet Another String Matching Problem(并查集 + FFT)

    题目链接  Educational Codeforces Round 40  Problem I 题意  定义两个长度相等的字符串之间的距离为:   把两个字符串中所有同一种字符变成另外一种,使得两个 ...

  6. Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式

    建立声明层表对象的两种方式 在对表对象进行建立的时候,通常有两种方式可以完成,以下是两种方式的建立过程对比 首先导入需要的模块,获取一个声明层 from sqlalchemy.sql.schema i ...

  7. numpy 多维数组的存取

    多维数组的存取和一维数组类似,由于多维数组有多个轴,所以他的下标需要多个值来表示.这里讨论的主要是二维数组.二维数组0轴以行为单位,1轴以列为单位,存取数组使用元组作为下标,需要注意的是,python ...

  8. OPENDJ的安装图文说明

    一. 说明 介绍: opendj是一个ldap服务器 用于存储openam的配置和用户存储信息 准备工具: OpenDJ-3.0.0.zip 二. 安装步骤 a) Linux安装过程 1. 将zip包 ...

  9. GPU hang

    最近做新项目 初期一直遇到个gpu hang的问题 就是command 提交过去gpu 就一直在那里 直到time out 也没什么别的错误提示 gpu debugger还抓不了 解决方案是 缩小之后 ...

  10. Camera图像处理原理及实例分析

    Camera图像处理原理及实例分析 作者:刘旭晖  colorant@163.com  转载请注明出处 BLOG:http://blog.csdn.net/colorant/ 主页:http://rg ...