• 转载 Android实现ListView异步加载图片


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

    Java代码  收藏代码
    1. package cn.wangmeng.test;  
    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. }  


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

    Java代码  收藏代码
    1. package cn.wangmeng.test;  
    2.   
    3. public class ImageAndText {  
    4.         private String imageUrl;  
    5.         private String text;  
    6.   
    7.         public ImageAndText(String imageUrl, String text) {  
    8.             this.imageUrl = imageUrl;  
    9.             this.text = text;  
    10.         }  
    11.         public String getImageUrl() {  
    12.             return imageUrl;  
    13.         }  
    14.         public String getText() {  
    15.             return text;  
    16.         }  
    17. }  
    Java代码  收藏代码
    1. package cn.wangmeng.test;  
    2.   
    3. import android.view.View;  
    4. import android.widget.ImageView;  
    5. import android.widget.TextView;  
    6.   
    7. public class ViewCache {  
    8.   
    9.         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的子元素布局

    Java代码  收藏代码
    1. package cn.wangmeng.test;  
    2.   
    3. import java.util.List;  
    4.   
    5. import cn.wangmeng.test.AsyncImageLoader.ImageCallback;  
    6.   
    7. import android.app.Activity;  
    8. import android.graphics.drawable.Drawable;  
    9. 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,大家仔细阅读就知道了。
    最后贴出布局文件:

    Xml代码  收藏代码
    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.   
    7.         <ImageView android:id="@+id/image"  
    8.                    android:layout_width="wrap_content"  
    9.                    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>  



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

  • 相关阅读:
    RMQ(非log2储存方法)
    2016年5月份学习记录
    NOIP200504循环
    膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)
    最长公共子序列的长度
    菜鸟,大牛和教主三者的区别(转自hzwer)
    NOIP201205Vigenère密码
    NOIP200503采药
    公路乘车
    NOIP200902分数线划定
  • 原文地址:https://www.cnblogs.com/xiao0/p/2172229.html
Copyright © 2020-2023  润新知