zoukankan      html  css  js  c++  java
  • 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;
    }
     
    }
    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>
  • 相关阅读:
    Python 学习笔记(二)开发环境的搭建
    Python 学习笔记(一)Python 简介
    android.os.NetworkOnMainThreadException
    Android Call requires API level 11 (current min is 8)的解决方案
    Linux命令top 详解
    主流nosql数据库对比
    MongoDB的常用命令
    MongoDB添加用户验证
    MongoDB
    html介绍
  • 原文地址:https://www.cnblogs.com/top5/p/2414275.html
Copyright © 2011-2022 走看看