Android实现ListView异步加载图片

本文介绍如何在Android中实现ListView的异步加载图片功能,通过使用软引用和回调函数,提高用户体验并减少等待时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,不用让用户等待下去,下面就说实现方法,先贴上主方法的代码: 
01. package cn.wangmeng.test;
02.  
03. import java.io.IOException;
04. import java.io.InputStream;
05. import java.lang.ref.SoftReference;
06. import java.net.MalformedURLException;
07. import java.net.URL;
08. import java.util.HashMap;
09.  
10. import android.graphics.drawable.Drawable;
11. import android.os.Handler;
12. import android.os.Message;
13.  
14. public class AsyncImageLoader {
15.  
16.      private HashMap<String, SoftReference<Drawable>> imageCache;
17.        
18.          public AsyncImageLoader() {
19.              imageCache = new HashMap<String, SoftReference<Drawable>>();
20.          }
21.        
22.          public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
23.              if (imageCache.containsKey(imageUrl)) {
24.                  SoftReference<Drawable> softReference = imageCache.get(imageUrl);
25.                  Drawable drawable = softReference.get();
26.                  if (drawable != null) {
27.                      return drawable;
28.                  }
29.              }
30.              final Handler handler = new Handler() {
31.                  public void handleMessage(Message message) {
32.                      imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
33.                  }
34.              };
35.              new Thread() {
36.                  @Override
37.                  public void run() {
38.                      Drawable drawable = loadImageFromUrl(imageUrl);
39.                      imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
40.                      Message message = handler.obtainMessage(0, drawable);
41.                      handler.sendMessage(message);
42.                  }
43.              }.start();
44.              return null;
45.          }
46.        
47.         public static Drawable loadImageFromUrl(String url) {
48.             URL m;
49.             InputStream i = null;
50.             try {
51.                 m = new URL(url);
52.                 i = (InputStream) m.getContent();
53.             catch (MalformedURLException e1) {
54.                 e1.printStackTrace();
55.             catch (IOException e) {
56.                 e.printStackTrace();
57.             }
58.             Drawable d = Drawable.createFromStream(i, "src");
59.             return d;
60.         }
61.        
62.          public interface ImageCallback {
63.              public void imageLoaded(Drawable imageDrawable, String imageUrl);
64.          }
65.  
66. }
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。 
几个辅助类文件:
01. package cn.wangmeng.test;
02.  
03. public class ImageAndText {
04.         private String imageUrl;
05.         private String text;
06.  
07.         public ImageAndText(String imageUrl, String text) {
08.             this.imageUrl = imageUrl;
09.             this.text = text;
10.         }
11.         public String getImageUrl() {
12.             return imageUrl;
13.         }
14.         public String getText() {
15.             return text;
16.         }
17. }
01. package cn.wangmeng.test;
02.  
03. import android.view.View;
04. import android.widget.ImageView;
05. import android.widget.TextView;
06.  
07. public class ViewCache {
08.  
09.         private View baseView;
10.         private TextView textView;
11.         private ImageView imageView;
12.  
13.         public ViewCache(View baseView) {
14.             this.baseView = baseView;
15.         }
16.  
17.         public TextView getTextView() {
18.             if (textView == null) {
19.                 textView = (TextView) baseView.findViewById(R.id.text);
20.             }
21.             return textView;
22.         }
23.  
24.         public ImageView getImageView() {
25.             if (imageView == null) {
26.                 imageView = (ImageView) baseView.findViewById(R.id.image);
27.             }
28.             return imageView;
29.         }
30.  
31. }

ViewCache是辅助获取adapter的子元素布局 
01. package cn.wangmeng.test;
02.  
03. import java.util.List;
04.  
05. import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
06.  
07. import android.app.Activity;
08. import android.graphics.drawable.Drawable;
09. import android.view.LayoutInflater;
10. import android.view.View;
11. import android.view.ViewGroup;
12. import android.widget.ArrayAdapter;
13. import android.widget.ImageView;
14. import android.widget.ListView;
15. import android.widget.TextView;
16.  
17. public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
18.  
19.         private ListView listView;
20.         private AsyncImageLoader asyncImageLoader;
21.  
22.         public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
23.             super(activity, 0, imageAndTexts);
24.             this.listView = listView;
25.             asyncImageLoader = new AsyncImageLoader();
26.         }
27.  
28.         public View getView(int position, View convertView, ViewGroup parent) {
29.             Activity activity = (Activity) getContext();
30.  
31.             // Inflate the views from XML
32.             View rowView = convertView;
33.             ViewCache viewCache;
34.             if (rowView == null) {
35.                 LayoutInflater inflater = activity.getLayoutInflater();
36.                 rowView = inflater.inflate(R.layout.image_and_text_row, null);
37.                 viewCache = new ViewCache(rowView);
38.                 rowView.setTag(viewCache);
39.             else {
40.                 viewCache = (ViewCache) rowView.getTag();
41.             }
42.             ImageAndText imageAndText = getItem(position);
43.  
44.             // Load the image and set it on the ImageView
45.             String imageUrl = imageAndText.getImageUrl();
46.             ImageView imageView = viewCache.getImageView();
47.             imageView.setTag(imageUrl);
48.             Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
49.                 public void imageLoaded(Drawable imageDrawable, String imageUrl) {
50.                     ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
51.                     if (imageViewByTag != null) {
52.                         imageViewByTag.setImageDrawable(imageDrawable);
53.                     }
54.                 }
55.             });
56.             if (cachedImage == null) {
57.                 imageView.setImageResource(R.drawable.default_image);
58.             }else{
59.                 imageView.setImageDrawable(cachedImage);
60.             }
61.             // Set the text on the TextView
62.             TextView textView = viewCache.getTextView();
63.             textView.setText(imageAndText.getText());
64.  
65.             return rowView;
66.         }
67.  
68. }

ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。 
最后贴出布局文件:
01. <?xml version="1.0" encoding="utf-8"?>
02. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03.               android:orientation="horizontal"
04.               android:layout_width="fill_parent"
05.               android:layout_height="wrap_content">
06.  
07.         <ImageView android:id="@+id/image"
08.                    android:layout_width="wrap_content"
09.                    android:layout_height="wrap_content"
10.                    />
11.  
12.         <TextView android:id="@+id/text"
13.                   android:layout_width="wrap_content"
14.                   android:layout_height="wrap_content"/>
15.  
16. </LinearLayout>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值