我现在想要用android的listview来显示从服务器上下载的图片该怎么做?像图片中这样
1条回答
- songhuidanoop 2011-04-21 17:33关注
第一步:分析api
使用ListView都需要使用Adapter,而api中的adapter都继承自BaseAdapter,所以第一反应就是自己实现一个继承自BaseAdapter的adapter,但是BaseAdapter还是属于高度抽象的基类,所以实现起来还是还是有点难度的。此时作为初学者的你(当然我也是啦)应该最熟悉的是SimpleAdapter了吧,而且SimpleAdapter也可以实现在ListView显示图片,但是就是不能显示网络图片,只能显示在drawalbe中定义过的图片。所以就想,我是否可以改写SimpleAdapter的类,在它实例化drawalbe中图片时,我替换成我自己 的显示网络图片的方法呢?答案是肯定的!(想获取android的源码,可以查看我的另一篇文章http://hulefei29.iteye.com/blog/615016)
第二步:源码分析
经过查看源码SimpleAdapter发现,显示每个item视图都是通过调用(int position, View convertView, ViewGroup parent)方法来实现的
Java代码
/**
* @see android.widget.Adapter#getView(int, View, ViewGroup)
/
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}
/*
* @see android.widget.Adapter#getView(int, View, ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}
在getView(int position, View convertView, ViewGroup parent)中又调用了SimpleAdapter的私有方法createViewFromResource来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from和int[] to进行了组装,代码如下:
Java代码
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);final int[] to = mTo; final int count = to.length; final View[] holder = new View[count]; for (int i = 0; i < count; i++) { holder[i] = v.findViewById(to[i]); } v.setTag(holder); } else { v = convertView; } bindView(position, v); return v; }
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);final int[] to = mTo; final int count = to.length; final View[] holder = new View[count]; for (int i = 0; i < count; i++) { holder[i] = v.findViewById(to[i]); } v.setTag(holder); } else { v = convertView; } bindView(position, v); return v; }
在createViewFromResource方法中又有一个bindView(position, v)方法对item中的各个View进行了组装,bindView(position, v)代码如下:
Java代码
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}final ViewBinder binder = mViewBinder; final View[] holder = (View[]) view.getTag(); final String[] from = mFrom; final int[] to = mTo; final int count = to.length; for (int i = 0; i < count; i++) { final View v = holder[i]; if (v != null) { final Object data = dataSet.get(from[i]); String text = data == null ? "" : data.toString(); if (text == null) { text = ""; } boolean bound = false; if (binder != null) { bound = binder.setViewValue(v, data, text); } if (!bound) { if (v instanceof Checkable) { if (data instanceof Boolean) { ((Checkable) v).setChecked((Boolean) data); } else { throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + data.getClass()); } } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else if (v instanceof ImageView) { if (data instanceof Integer) { setViewImage((ImageView) v, (Integer) data); } else { setViewImage((ImageView) v, text); } } else { throw new IllegalStateException(v.getClass().getName() + " is not a " + " view that can be bounds by this SimpleAdapter"); } } } } }
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}final ViewBinder binder = mViewBinder; final View[] holder = (View[]) view.getTag(); final String[] from = mFrom; final int[] to = mTo; final int count = to.length; for (int i = 0; i < count; i++) { final View v = holder[i]; if (v != null) { final Object data = dataSet.get(from[i]); String text = data == null ? "" : data.toString(); if (text == null) { text = ""; } boolean bound = false; if (binder != null) { bound = binder.setViewValue(v, data, text); } if (!bound) { if (v instanceof Checkable) { if (data instanceof Boolean) { ((Checkable) v).setChecked((Boolean) data); } else { throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + data.getClass()); } } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else if (v instanceof ImageView) { if (data instanceof Integer) { setViewImage((ImageView) v, (Integer) data); } else { setViewImage((ImageView) v, text); } } else { throw new IllegalStateException(v.getClass().getName() + " is not a " + " view that can be bounds by this SimpleAdapter"); } } } } }
终于找到了对ViewImage进行组装的代码了“else if (v instanceof ImageView)”,我们留成功之差一步之遥了!
看到上面茫茫的代码是不是已经头晕了呢,其实以上的都是源代码,我没有做过任何的修改,也不需要修改,只是需要把它从SimpleAdapter中取出来进行覆盖,以为他们私有方法,不能用super调用!到最后终于到你出手的时候了,你需要重写SimpleAdapter类中的setViewText方法,SimpleAdapter对setViewText进行了重载,有两个方法,代码如下:
Java代码
public void setViewImage(ImageView v, int value) {
v.setImageResource(value);
}public void setViewImage(ImageView v, String value) {
try {
v.setImageResource(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
v.setImageURI(Uri.parse(value));
}
}
public void setViewImage(ImageView v, int value) {
v.setImageResource(value);
}public void setViewImage(ImageView v, String value) { try { v.setImageResource(Integer.parseInt(value)); } catch (NumberFormatException nfe) { v.setImageURI(Uri.parse(value)); } }setViewImage(ImageView v, int value) 你应该一看就熟悉了吧,int就是R中的索引值,但是你还看到SimpleAdapter居然还有一个setViewImage(ImageView v, String value)可以接受String的方法,在往下看就是知道了,如果不是索引,ImageView 也可以接受Uri的值来设置图片,切忌Uri不是Url,所以我们只需要改写一下这个方法就ok了,代码如下:
Java代码
public void setViewImage(ImageView v, String value) {
Bitmap bitmap = WebImageBuilder.returnBitMap(value);
((ImageView) v).setImageBitmap(bitmap);
}
public void setViewImage(ImageView v, String value) {
Bitmap bitmap = WebImageBuilder.returnBitMap(value);
((ImageView) v).setImageBitmap(bitmap);
}我们用Bitmap 来对ImageView进行设置,WebImageBuilder.returnBitMap是我自己实现的获取网络图片的方法,当然google下都是的,在我下面的源码中也有,在这里就不多说了!说到这,我的解释也就说完了,希望可以给你帮助!如果你是不愿意跟着别人思路走的人,希望自己研究出来的话,那最后我也拿我的源码贴上,对有些朋友来说获取直接看源码,理解的更快吧!最后强调一下,本文为胡乐费的原创,如果要转载的话,希望注明出处!
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 镍氢电池充电器设计实物使用原理
- ¥15 逻辑谓词和消解原理的运用
- ¥15 三菱伺服电机按启动按钮有使能但不动作
- ¥15 js,页面2返回页面1时定位进入的设备
- ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
- ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
- ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
- ¥20 腾讯企业邮箱邮件可以恢复么
- ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
- ¥15 错误 LNK2001 无法解析的外部符号