Android实现异步加载图片 ListView(转)

来源:互联网 发布:远程网络教学系统类图 编辑:程序博客网 时间:2024/05/21 17:03
ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码: 

Java代码


  1. package com.dragon.example;    
  2.     
  3. import java.io.IOException;    
  4. import java.io.InputStream;    
  5. import java.lang.ref.SoftReference;    
  6. import java.net.MalformedURLException;    
  7. import java.net.URL;    
  8. import java.util.HashMap;    
  9.     
  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. }    
  67.   
  68. 以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。   
  69. 几个辅助类文件:   
  70. package com.dragon.example;  
  71.   
  72. public class ImageAndText {    
  73.         private String imageUrl;    
  74.         private String text;    
  75.     
  76.         public ImageAndText(String imageUrl, String text) {    
  77.             this.imageUrl = imageUrl;    
  78.             this.text = text;    
  79.         }    
  80.         public String getImageUrl() {    
  81.             return imageUrl;    
  82.         }    
  83.         public String getText() {    
  84.             return text;    
  85.         }    
  86. }    
  87.   
  88.   
  89. package com.dragon.example;      
  90.   
  91. import android.view.View;    
  92. import android.widget.ImageView;    
  93. import android.widget.TextView;    
  94.     
  95. public class ViewCache {    
  96.     
  97.         private View baseView;    
  98.         private TextView textView;    
  99.         private ImageView imageView;    
  100.     
  101.         public ViewCache(View baseView) {    
  102.             this.baseView = baseView;    
  103.         }    
  104.     
  105.         public TextView getTextView() {    
  106.             if (textView == null) {    
  107.                 textView = (TextView) baseView.findViewById(R.id.text);    
  108.             }    
  109.             return textView;    
  110.         }    
  111.     
  112.         public ImageView getImageView() {    
  113.             if (imageView == null) {    
  114.                 imageView = (ImageView) baseView.findViewById(R.id.image);    
  115.             }    
  116.             return imageView;    
  117.         }    
  118.     
  119. }   
  120.   
  121. ViewCache是辅助获取adapter的子元素布局   
  122. package com.dragon.example;   
  123.   
  124. import java.util.List;    
  125.     
  126. import com.dragon.example.AsyncImageLoader.ImageCallback;    
  127.     
  128. import android.app.Activity;    
  129. import android.graphics.drawable.Drawable;    
  130. import android.view.LayoutInflater;    
  131. import android.view.View;    
  132. import android.view.ViewGroup;    
  133. import android.widget.ArrayAdapter;    
  134. import android.widget.ImageView;    
  135. import android.widget.ListView;    
  136. import android.widget.TextView;    
  137.     
  138. public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {    
  139.     
  140.         private ListView listView;    
  141.         private AsyncImageLoader asyncImageLoader;    
  142.     
  143.         public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {    
  144.             super(activity, 0, imageAndTexts);    
  145.             this.listView = listView;    
  146.             asyncImageLoader = new AsyncImageLoader();    
  147.         }    
  148.     
  149.         public View getView(int position, View convertView, ViewGroup parent) {    
  150.             Activity activity = (Activity) getContext();    
  151.     
  152.             // Inflate the views from XML    
  153.             View rowView = convertView;    
  154.             ViewCache viewCache;    
  155.             if (rowView == null) {    
  156.                 LayoutInflater inflater = activity.getLayoutInflater();    
  157.                 rowView = inflater.inflate(R.layout.image_and_text_row, null);    
  158.                 viewCache = new ViewCache(rowView);    
  159.                 rowView.setTag(viewCache);    
  160.             } else {    
  161.                 viewCache = (ViewCache) rowView.getTag();    
  162.             }    
  163.             ImageAndText imageAndText = getItem(position);    
  164.     
  165.             // Load the image and set it on the ImageView    
  166.             String imageUrl = imageAndText.getImageUrl();    
  167.             ImageView imageView = viewCache.getImageView();    
  168.             imageView.setTag(imageUrl);    
  169.             Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {    
  170.                 public void imageLoaded(Drawable imageDrawable, String imageUrl) {    
  171.                     ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);    
  172.                     if (imageViewByTag != null) {    
  173.                         imageViewByTag.setImageDrawable(imageDrawable);    
  174.                     }    
  175.                 }    
  176.             });    
  177.             if (cachedImage == null) {    
  178.                 imageView.setImageResource(R.drawable.default_image);    
  179.             }else{    
  180.                 imageView.setImageDrawable(cachedImage);    
  181.             }    
  182.             // Set the text on the TextView    
  183.             TextView textView = viewCache.getTextView();    
  184.             textView.setText(imageAndText.getText());    
  185.     
  186.             return rowView;    
  187.         }    
  188.     
  189. }    
  190.   
  191. ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。   
  192. 最后贴出布局文件:   
  193. Xml代码   
  194. <?xml version="1.0" encoding="utf-8"?>    
  195. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  196.               android:orientation="horizontal"    
  197.               android:layout_width="fill_parent"    
  198.               android:layout_height="wrap_content">    
  199.     
  200.         <ImageView android:id="@+id/image"    
  201.                    android:layout_width="wrap_content"    
  202.                    android:layout_height="wrap_content"    
  203.                    />    
  204.     
  205.         <TextView android:id="@+id/text"    
  206.                   android:layout_width="wrap_content"    
  207.                   android:layout_height="wrap_content"/>    
  208.     
  209. </LinearLayout>