IT源码网

Android实现ListView异步加载图片

shasha 2021年04月03日 程序员 412 0

ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好

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);    
         }    
   
}  
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线程。

几个辅助类文件:

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;    
        }    
}  
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; 
     } 
} 
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的子元素布局

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;    
        }    
   
}  
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; 
     } 
} 

ImageAndTextListAdapter是实现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> 

 

评论关闭
IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!