欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-16 16:49:52
本文实例讲述了android实现listview异步加载图片的方法。分享给大家供大家参考。具体如下: 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>

运行效果截图如下:

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

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