Android實現ListView異步加載圖片
編輯:初級開發
ListVIEw異步加載圖片是非常實用的方法,凡是是要通過網絡獲取圖片資源一般使用這種方法比較好,用戶體驗好,下面就說實現方法,先貼上主方法的代碼:
- package cn.wangmeng.test;
- 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.drawable.Drawable;
- import android.os.Handler;
- import android.os.Message;
- public class AsyncImageLoader {
- private HashMap<String, SoftReference<Drawable>> imageCache;
-
- public AsyncImageLoader() {
- imageCache = new HashMap<String, SoftReference<Drawable>>();
- }
-
- public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
- if (imageCache.containsKey(imageUrl)) {
- SoftReference<Drawable> softReference = imageCache.get(imageUrl);
- Drawable drawable = softReference.get();
- if (drawable != null) {
- return drawable;
- }
- }
- final Handler handler = new Handler() {
- public void handleMessage(Message message) {
- imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
- }
- };
- new Thread() {
- @Override
- public void run() {
- Drawable drawable = loadImageFromUrl(imageUrl);
- imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
- Message message = handler.obtainMessage(0, drawable);
- handler.sendMessage(message);
- }
- }.start();
- return null;
- }
-
- public static Drawable loadImageFromUrl(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();
- }
- Drawable d = Drawable.createFromStream(i, "src");
- return d;
- }
-
- public interface ImageCallback {
- public void imageLoaded(Drawable imageDrawable, String imageUrl);
- }
- }
以上代碼是實現異步獲取圖片的主方法,SoftReference是軟引用,是為了更好的為了系統回收變量,重復的URL直接返回已有的資源,實現回調函數,讓數據成功後,更新到UI線程。
幾個輔助類文件:
- package cn.wangmeng.test;
- public class ImageAndText {
- private String imageUrl;
- private String text;
- public ImageAndText(String imageUrl, String text) {
- this.imageUrl = imageUrl;
- this.text = text;
- }
- public String getImageUrl() {
- return imageUrl;
- }
- public String getText() {
- return text;
- }
- }
- package cn.wangmeng.test;
- import android.view.VIEw;
- import android.widget.ImageVIEw;
- import android.widget.TextVIEw;
- public class VIEwCache {
- private View baseVIEw;
- private TextView textVIEw;
- private ImageView imageVIEw;
- public ViewCache(View baseVIEw) {
- this.baseView = baseVIEw;
- }
- public TextView getTextVIEw() {
- if (textVIEw == null) {
- textView = (TextView) baseView.findVIEwById(R.id.text);
- }
- return textVIEw;
- }
- public ImageView getImageVIEw() {
- if (imageVIEw == null) {
- imageView = (ImageView) baseView.findVIEwById(R.id.image);
- }
- return imageVIEw;
- }
- }
VIEwCache是輔助獲取adapter的子元素布局
- package cn.wangmeng.test;
- import Java.util.List;
- import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
- import android.app.Activity;
- import android.graphics.drawable.Drawable;
- import android.vIEw.LayoutInflater;
- import android.view.VIEw;
- import android.view.VIEwGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ImageVIEw;
- import android.widget.ListVIEw;
- import android.widget.TextVIEw;
- public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
- private ListView listVIEw;
- private AsyncImageLoader asyncImageLoader;
- public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listVIEw) {
- super(activity, 0, imageAndTexts);
- this.listView = listVIEw;
- asyncImageLoader = new AsyncImageLoader();
- }
- public View getView(int position, View convertView, VIEwGroup parent) {
- Activity activity = (Activity) getContext();
- // Inflate the vIEws from XML
- View rowView = convertVIEw;
- ViewCache vIEwCache;
- if (rowVIEw == null) {
- LayoutInflater inflater = activity.getLayoutInflater();
- rowVIEw = inflater.inflate(R.layout.image_and_text_row, null);
- viewCache = new ViewCache(rowVIEw);
- rowView.setTag(vIEwCache);
- } else {
- viewCache = (ViewCache) rowVIEw.getTag();
- }
- ImageAndText imageAndText = getItem(position);
- // Load the image and set it on the ImageVIEw
- String imageUrl = imageAndText.getImageUrl();
- ImageView imageView = viewCache.getImageVIEw();
- imageVIEw.setTag(imageUrl);
- Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
- public void imageLoaded(Drawable imageDrawable, String imageUrl) {
- ImageView imageViewByTag = (ImageView) listView.findVIEwWithTag(imageUrl);
- if (imageVIEwByTag != null) {
- imageVIEwByTag.setImageDrawable(imageDrawable);
- }
- }
- });
- if (cachedImage == null) {
- imageVIEw.setImageResource(R.drawable.default_image);
- }else{
- imageVIEw.setImageDrawable(cachedImage);
- }
- // Set the text on the TextVIEw
- TextView textView = viewCache.getTextVIEw();
- textVIEw.setText(imageAndText.getText());
- return rowVIEw;
- }
- }
mageAndTextListAdapter是實現ListView的Adapter,裡面有個技巧就是imageVIEw.setTag(imageUrl),setTag是存儲數據的,這樣是為了保證在回調函數時,listvIEw去更新自己對應item,大家仔細閱讀就知道了。
最後貼出布局文件:
- <?XML version="1.0" encoding="utf-8"?>
- <LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
- android:orIEntation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <ImageVIEw android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <TextVIEw android:id="@+id/text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </LinearLayout>
- 上一頁:Android用gallery控件實現游戲開發之選關畫面
- 下一頁:Android Google translate api例子