`
Function
  • 浏览: 64239 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

ListView异步加载图片

 
阅读更多
关于ListView异步加载图片有很多方式,也有很多方法可以解决图片错位的现象,看完他们写的代码,多半是基于回调的方式,比如这位:http://www.iteye.com/topic/685986
他解决错位的方式很巧妙:
ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
在构造适配器是传入ListView的引用,由唯一的TAG来找显示的ImageView;
还有这位:http://www.iteye.com/topic/1118828
为了提升用户的体验效果,使用了线程等待。

下面分享我的方法:
也没有考虑到加载数量多的图片,和大图片,这些用户可以根据自己需要用ThumbnailUtils类进行处理,关于一次启动几十个线程的问题,我感觉没有担心的必要,感觉分页就可以解决。
下面贴代码(可以处理加载网络图片和本地图片):
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

/**
 * 图片异步加载工具类
 * 
 * @version V1.0
 */
public class AsynImageLoader {

	// 图片软引用
	private HashMap<String, SoftReference<Bitmap>> imageCache;
	// 显示图片的ImageView
	private HashMap<String, ImageView> imageViews;

	public AsynImageLoader() {// 构造
		imageCache = new HashMap<String, SoftReference<Bitmap>>();
		imageViews = new HashMap<String, ImageView>();
	}

	/**
	 * 从网络上获取图片
	 * 
	 * @param imageView
	 *            显示图片的ImageView
	 * @param imageUrl
	 *            图片的地址
	 * @return 图片
	 */
	public Bitmap loadDrawableFromNet(final ImageView imageView,
			final String imageUrl) {
		return loadDrawable(imageView, imageUrl, new LoadCallBack() {
			public Bitmap load(String uri) {
				return loadImageFromNet(uri);
			}
		});
	}

	/**
	 * 从本地获取图片
	 * 
	 * @param imageView
	 *            显示图片的ImageView
	 * @param imageUrl
	 *            图片的路径
	 * @return 图片
	 */
	public Bitmap loadDrawableFromLocal(final ImageView imageView,
			final String imageUrl) {
		return loadDrawable(imageView, imageUrl, new LoadCallBack() {
			public Bitmap load(String uri) {
				return loadImageFromLocal(uri);
			}
		});
	}

	/**
	 * 获取图片
	 * 
	 * @param imageView
	 *            显示图片的ImageView
	 * @param imageUrl
	 *            图片路径或网络地址
	 * @param load
	 *            回调方法 加载本地图片或者加载网络图片
	 * @return
	 */
	private Bitmap loadDrawable(final ImageView imageView,
			final String imageUrl, final LoadCallBack load) {

		// 判断软引用里是否有图片
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			Bitmap bitmap = softReference.get();
			if (bitmap != null) {
				return bitmap;// 有则返回
			}
		}

		// 将为添加到图片显示集合的 ImageViwe 加入到集合
		if (!imageViews.containsKey(imageUrl)) {
			imageViews.put(imageUrl, imageView);
		}

		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageViews.get(imageUrl).setImageBitmap((Bitmap) message.obj);
			}
		};

		//启动线程获取图片
		new Thread() {
			public void run() {
				Bitmap bitmap = load.load(imageUrl);//执行回调
				imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
				Message message = handler.obtainMessage(0, bitmap);
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}

	private interface LoadCallBack {
		public Bitmap load(String uri);
	}

	/**
	 * 从网络加载图片
	 * 
	 * @param url
	 * @return
	 */
	public Bitmap loadImageFromNet(String url) {
		URL m;
		InputStream i = null;
		try {
			m = new URL(url);
			i = (InputStream) m.getContent();
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return BitmapFactory.decodeStream(i);
	}

	/**
	 * 从本地加载图片
	 * 
	 * @param path
	 * @return
	 */
	public Bitmap loadImageFromLocal(String path) {
		return BitmapFactory.decodeFile(path);
	}
}


这个处理方式没有用到回调,没让ListView传入Adapter,没让Adapter里的代码显得那么臃肿,下面贴两行调用:
Bitmap cachedImage = loader.loadDrawableFromNet(item.imageView,url);
item.setImageBitmap(cachedImage);


核心的思想就是在加载类里面做一个集合来存放显示的ImageView

--写码笔记,欢迎交流
分享到:
评论
1 楼 mitty 2013-02-26  
    

相关推荐

    android listview异步加载图片实例(线程池+数据库+本地保存)

    本实例将详细讲解如何实现“Android ListView异步加载图片”,结合线程池、数据库和本地保存来优化性能。 首先,我们需要理解异步加载的概念。在Android中,由于主线程负责用户界面的更新,因此不应在主线程中执行...

    Android实现ListView异步加载图片

    "Android实现ListView异步加载图片" Android 实现 ListView 异步加载图片是一种常见的技术,旨在提高应用程序的性能和用户体验。本文将详细介绍 Android 中实现 ListView 异步加载图片的方法,并对相关的技术概念...

    listview 异步加载图片

    因此,"ListView异步加载图片"是解决这一问题的关键技术。本文将详细介绍如何在ListView中实现图片的异步加载,提升用户体验。 1. **AsyncTask**:Android提供了异步处理任务的工具类AsyncTask,可以用来加载图片。...

    android listView 异步加载图片

    这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...

    ListView异步加载图片进度条

    综上所述,实现ListView中的异步加载图片进度条,需要综合运用多线程、图片缓存、UI更新等技术,并遵循良好的代码组织和错误处理原则。通过合理的封装和接口设计,可以使得代码更加规范,同时也提升了用户体验。

    listView 异步加载图片

    因此,"ListView异步加载图片"是一个重要的优化策略,旨在提高用户体验并减少资源消耗。 1. **异步加载原理**: 异步加载图片的核心思想是将耗时的网络请求和图片解码操作放在后台线程执行,避免阻塞UI主线程。...

    listview异步加载图片

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。...综上所述,Android ListView异步加载图片是提高应用性能的关键技术,通过合理的线程管理和第三方库,我们可以高效、便捷地实现这一功能。

    官方 listview 异步加载图片

    "官方 listview 异步加载图片"这个主题就是关于如何在ListView中高效、平滑地加载图片的技术实践。 异步加载的基本原理是在主线程之外(通常在后台线程)加载图片,避免阻塞UI更新,从而保证界面的流畅性。在这个...

    listview 异步加载图片,滑动删除

    在本项目"listview 异步加载图片,滑动删除"中,开发者实现了一个功能完善的ListView,它不仅能够异步加载图片,还支持用户通过滑动来删除列表项。 1. **异步加载图片**:异步加载是一种优化策略,避免阻塞主线程,...

    listView异步加载图片实例

    因此,"ListView异步加载图片实例"是一个重要的优化策略,它的目的是在不阻塞主线程的情况下加载图片,提升用户体验。 异步加载图片的基本原理是将图片的加载工作放在后台线程执行,完成后再更新到ListView的相应...

    listview 异步加载图片源代码

    本文将基于提供的"listview 异步加载图片源代码",详细讲解如何实现ListView中图片的异步加载。 首先,异步加载图片的核心思想是将耗时的操作,即图片的下载和解码工作,放到后台线程进行,避免阻塞主线程。这样...

    Android ListView异步加载图片

    Android 异步加载图片,对ListView的异步加载图片的功能演示,主要根据url读取图片返回流的方法。为了方便演示,将请求图片的链接先固定,每读取好一个图片就更新,界面比较简单,当然你可以做成比较好的,像很多好...

Global site tag (gtag.js) - Google Analytics