关于ListView中动态获取图片的问题

来公司快三个月了,因为项目紧,很长一段时间没有发表博文了,做了两个项目,功能差不多,下面简单说明一下有哪些功能

就相当于国内的新浪微博或者腾讯微博客户端之类的,请求并解析从网络获取到的特定格式的xml数据,按照一定的格式显示出来,首页是一个ListView,这点不用说吧,点击某个item的时候跳转到详细页面,在详细页面可以发表评论,可以分享到Twitter,这里用到一个控件,叫PopupWindow,记得当时弄这个东西弄了几天才实现,对于分享到Twitter,这也是个难点,之前发表了一篇博文,好像没怎么讲清楚,很多人在问我,大家的问题基本上都是我之前遇到过的,在创建应用的时候一定要设置CALLBACK_URL这个值,可以是https://api.twitter.com/oauth/authorize?oauth_token,如果不设置它的话,当验证通过了不会跳转的,只是在页面上显示一串的数字,我也不知道那数字有什么用,如果设置了这个CALLBACK_URL,当验证成功了就会跳转,并且返回的时候还会在这个url后面加上一些参数,比如accesstoken之类的,这个值可以存起来,之后重新发表的时候把这个参数附带上就行了,就不用再验证。

今天我不打算讲Twitter这一块,讲讲在ListView中动态获取图片吧

首先介绍一个类,这个类也是在网上找的,有的有点问题,稍微做了一些修改,直接拿来就可以用的

AsyncImageLoader.java

package com.netafull.util;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

public class AsyncImageLoader {
private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();

public Drawable loadDrawable(final String imageUrl,
final ImageCallback callback) {
if (imageCache.containsKey(imageUrl)) {
SoftReference
<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
}
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
callback.imageLoaded((Drawable) msg.obj, imageUrl);
}
};
new Thread() {
public void run() {
Drawable drawable
= loadImageFromUrl(imageUrl);
imageCache.put(imageUrl,
new SoftReference<Drawable>(drawable));
handler.sendMessage(handler.obtainMessage(
0, drawable));
};
}.start();
return null;
}

protected Drawable loadImageFromUrl(String imageUrl) {
try {
return Drawable.createFromStream(new URL(imageUrl).openStream(),
"src");
}
catch (Exception e) {
// throw new RuntimeException(e);
//System.out.println(imageUrl);
return null;
}
}

public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}

}

  调用这个类的时候只需要传入一个imageUrl就行了,采用异步方式加载,所以不会对主线程造成影响

下面是Adapter

HomePageAdapter.java

package com.netafull.adapter;

import java.util.HashMap;
import java.util.List;

import com.netafull.R;
import com.netafull.analyze.News;
import com.netafull.util.AsyncImageLoader;
import com.netafull.util.AsyncImageLoader.ImageCallback;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class HomePageAdapter extends BaseAdapter {

public List<News> items;
Context context;
public HashMap<Integer, Drawable> hm;
private AsyncImageLoader asyncImageLoader;
int count = 0;

public HomePageAdapter(List<News> items, Context context) {
super();
this.items = items;
this.context = context;
hm
= new HashMap<Integer, Drawable>();
asyncImageLoader
= new AsyncImageLoader();
count
= items.size();
}

@Override
public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

@Override
public Object getItem(int arg0) {
return items.get(arg0);
}

@Override
public long getItemId(int arg0) {
return arg0;
}

@Override
public View getView(final int position, View convertView, ViewGroup arg2) {
News temp
= items.get(position);

View view
= null;
final ViewHolder holder = new ViewHolder();
String image_url
= temp.getImg_url();
// System.out.println(image_url);
if (image_url != null) {

view
= LayoutInflater.from(context).inflate(
R.layout.homepage_list_item,
null);
holder.tv_public_date
= (TextView) view
.findViewById(R.id.list_public_date);
holder.tv_public_date.setText(temp.getPublic_date());
holder.tv_title
= (TextView) view.findViewById(R.id.list_title);
holder.tv_title.getPaint().setFakeBoldText(
true);
holder.tv_title.setText(temp.getTitle());
holder.tv_description
= (TextView) view
.findViewById(R.id.list_description);
holder.tv_description.setText(temp.getDescription());
holder.iv_image
= (ImageView) view.findViewById(R.id.list_image);

// 动态加载图片

Drawable d
= hm.get(position);
if (d != null) {
holder.iv_image.setImageDrawable(d);
}
else {
asyncImageLoader.loadDrawable(image_url,
new ImageCallback() {

@Override
public void imageLoaded(Drawable imageDrawable,
String imageUrl) {
// TODO Auto-generated method stub
if (holder.iv_image != null && imageDrawable != null) {
holder.iv_image.setImageDrawable(imageDrawable);
hm.put(position, imageDrawable);

  

  我这里面做了一个判断哈,我先判断的image_url 是否为空,因为有的时候请求某个item的时候,xml文件中没有给出image_url数据,这时就没有图片,然后我就使用了另外的布局文件,以文字填充本来应该显示图片的内容。但这个不是重点。

此Adapter中定义了一个

public HashMap<Integer, Drawable> hm;

  用来存储相应位置上的图片,Integer表示item的id,Drawable自然就表示对应id的图片了,当取到图片的时候,就放进去,并设置好id

hm.put(position, imageDrawable);

  当然,首先要判断,某个id位置是否已经有图片,如果有的话就直接返回图片,并显示,如果没有的话,再请求。。。

Drawable d = hm.get(position);
if (d != null) {
holder.iv_image.setImageDrawable(d);
}
else {...}

  

  OK,就是这样吧,这个知识点先记录这么多,有问题直接留言哈,我看到后会回复的。。。

(由于最近公司iPhone项目特别多,准备学点iPhone开发,Android开发可能要隔段时间了。。。)

posted @ 2011-08-11 16:38  And.He  阅读(2956)  评论(2编辑  收藏  举报