Android实现ListView异步加载图片的方法

 更新时间:2015年10月15日 14:24:03   作者:白羽雕弓  
这篇文章主要介绍了Android实现ListView异步加载图片的方法,以实例形式较为详细的分析了Android中ListView异步加载图片的原理与相关实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了Android实现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>

运行效果截图如下:

希望本文所述对大家的C#程序设计有所帮助。

相关文章

  • 详解android系统的定制

    详解android系统的定制

    这篇内容给大家分享了关于android系统的定制的一些步骤和基本知识点,有兴趣的朋友参考学习下。
    2018-06-06
  • Android线程池控制并发数多线程下载

    Android线程池控制并发数多线程下载

    这篇文章主要为大家详细介绍了Android线程池控制并发数多线程下载,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Android仿微信布局的实现示例

    Android仿微信布局的实现示例

    本文主要介绍了Android仿微信布局的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Android改变ExpandableListView的indicator图标实现方法

    Android改变ExpandableListView的indicator图标实现方法

    这篇文章主要介绍了Android改变ExpandableListView的indicator图标实现方法,结合实例形式分析了改变ExpandableListView的indicator图标相关步骤与实现技巧,涉及Android配置文件的修改,需要的朋友可以参考下
    2016-03-03
  • Android实现按钮拖拽还原功能

    Android实现按钮拖拽还原功能

    这篇文章主要介绍了Android按钮拖拽还原功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • android通过servlet服务器保存文件到手机

    android通过servlet服务器保存文件到手机

    这篇文章主要为大家详细介绍了android通过servlet服务器保存文件到手机,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • 使用CMake构建OpenCV项目过程解析

    使用CMake构建OpenCV项目过程解析

    这篇文章主要介绍了使用CMake构建OpenCV项目过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Java操作Ant压缩和解压文件及批量打包Anroid应用

    Java操作Ant压缩和解压文件及批量打包Anroid应用

    这篇文章主要介绍了使用Java操作Ant压缩和解压文件以及批量打包Anroid应用的教程,Ant是一个自动化部署工具,用来处理zip和tar文件非常方便,需要的朋友可以参考下
    2016-02-02
  • Android ViewModel的作用深入讲解

    Android ViewModel的作用深入讲解

    这篇文章主要介绍了Android ViewModel的作用,ViewModel类旨在以注重生命周期的方式存储和管理界面相关数据,ViewModel类让数据可在发生屏幕旋转等配置更改后继续留存,需要详细了解可以参考下文
    2023-05-05
  • Android studio虚拟机在启动界面和桌面出现画面模糊花屏问题的解决方法

    Android studio虚拟机在启动界面和桌面出现画面模糊花屏问题的解决方法

    这篇文章主要介绍了解决Android studio虚拟机在启动界面和桌面出现画面模糊花屏问题,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2020-03-03

最新评论