关于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开发可能要隔段时间了。。。)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架