问题描述
- 如何在android中的ListView实现图片的异步加载?
- 想要实现对ListView Item 中图片的加载?各位帮忙怎么实现?
解决方案
我封装了一个异步加载类 开放源码并且提供示例代码
这是地址ImageAsyncLoader
解决方案二:
Java代码
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(isrc""); return d; } public interface ImageCallback { public void imageLoaded(Drawable imageDrawable String imageUrl); }
}
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
几个辅助类文件:
Java代码
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; }
}
Java代码
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的子元素布局
Java代码
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 {
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代码
<?xml version=""1.0"" encoding=""utf-8""?>
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""/>
解决方案三:
AsyncLoader或者AsyncTask都行,你看看apidemos里面的代码,有例子。。。。。。
解决方案四:
没仔细看,但是原来自己也是这么做的。楼主这是一篇提问帖还是一篇技术贴呀?