`

android ListView显示网络图片

阅读更多

研究了android两个礼拜,稍微有了点眉目,开始正式帮公司开发应用的时候,发现ListView没有现成的显示网络图片的类或方法,网上查了查也没找到好的解决方法。心一横,自己研究吧,现在把我的解决办法和大家分享一下。

 

使用ListView的方法就不在此介绍了,google一下都是的。

 

第一步:分析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)方法来实现的

/**
     * @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进行了组装,代码如下:

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)代码如下:

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进行了重载,有两个方法,代码如下:

    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了,代码如下:

public void setViewImage(ImageView v, String value) {
    	Bitmap bitmap = WebImageBuilder.returnBitMap(value);
    	((ImageView) v).setImageBitmap(bitmap);
    }

 我们用Bitmap 来对ImageView进行设置,WebImageBuilder.returnBitMap是我自己实现的获取网络图片的方法,当然google下都是的,在我下面的源码中也有,在这里就不多说了!说到这,我的解释也就说完了,希望可以给你帮助!如果你是不愿意跟着别人思路走的人,希望自己研究出来的话,那最后我也拿我的源码贴上,对有些朋友来说获取直接看源码,理解的更快吧!

 

最后强调一下,本文为胡乐费的原创,如果要转载的话,希望注明出处!

本文转自: http://hulefei29.iteye.com/blog/616262

 

 

分享到:
评论
14 楼 sanlie123456 2013-02-19  
请问下如何设置解析后图片的大小啊?谢谢
13 楼 sunnyting 2012-04-23  
正在开始学习Android,做一个客户端,正好用到了SimpleAdapter时候发现无法传图片,发现了这样的好文章非常开心,希望学习交流:)
12 楼 xiaojian623 2011-09-01  
加了几个item的确变得好卡,不过谢谢 楼主提供思路,我去改改!
11 楼 geek87 2011-04-13  
好精辟
10 楼 bing086 2011-03-09  
感谢感谢。
9 楼 f1jee 2011-02-14  
不错!但是我感觉javaeye误人子弟的文章不少!
8 楼 LoveZhou 2011-01-14  
感谢分享 
7 楼 javalover00000 2011-01-03  
我也遇到这个问题,只不过 我是想要显示的图片是sdcard里的图片,你的这篇文章 给我不少提示,很感谢!不过 我试过了,实际上 我们自己的adapter 只需要 重写 public void setViewImage(ImageView v, String value) 这个方法 就可以了和 构造方法 就好了!
6 楼 米其林的微笑 2010-12-12  
谢谢,找到你这份资料,终于解决了一个星期来的问题,知道自己错在哪了,这就去修改;
5 楼 hulefei29 2010-11-20  
好像很耗的说        就十几个item就搞得应用一直无法响应[/quote
是的,这是我最初接触android时写到,几乎不能用于生产,只用于学习。

推荐一个文档,会对你有帮助
http://www.hulefei.com/?p=81
4 楼 rocky_shi 2010-11-17  
好像很耗的说        就十几个item就搞得应用一直无法响应
3 楼 nrg19840409 2010-06-29  
感谢分享! 
2 楼 hulefei29 2010-06-09  
larryzou 写道
有改进的地方。imgview会在ui thread里面跑,最好开个workthread来下载,再set回去。

同意!
1 楼 larryzou 2010-06-01  
有改进的地方。imgview会在ui thread里面跑,最好开个workthread来下载,再set回去。

相关推荐

    Android ListView从网络获取图片及文字显示

    从网络加载图片显示到listview上,主函数布局是一个ListView item布局是TextView和ImageView 数量的多少视情况而定 再写一个网络请求数据的类 最后面有代码: ”urlConnection 请求数据类的封装“ 类名一定要一样...

    android listview 高效显示网络图片,自定义listview布局

    然而,当ListView中的每一项都需要显示网络图片时,如果不进行优化,可能会导致性能问题,如界面卡顿、滚动不流畅等。这个问题的解决方法是高效地加载网络图片并自定义ListView的布局。 首先,我们需要了解异步加载...

    Android ListView扩展(图片+文字)

    可以使用Picasso、Glide等库加载网络图片,或者使用Android的Bitmap类处理本地图片。 4. 设置ListView:在Activity中,获取ListView实例,然后设置Adapter。例如,`listView.setAdapter(adapter)`。这一步将数据源...

    listView显示网络图片

    本文将深入探讨如何在ListView中实现网络图片的加载与显示,以及解决图片错乱的问题。 首先,我们需要一个图片加载库来帮助我们处理网络图片的下载和显示。在Android社区中,有多个流行的图片加载库可供选择,如...

    android listview 加载网络图片(线程池+缓存管理) 高性能

    在Android开发中,ListView是展示大量数据的常用组件,但加载网络图片往往会给ListView的流畅性带来挑战。本文将深入探讨如何实现一个高性能的ListView,结合线程池和缓存管理来优化网络图片的加载。 首先,理解...

    Listview显示网络图片

    总之,"Listview显示网络图片"涉及到Android开发中的性能优化和用户体验设计。通过使用异步加载库如Glide,我们可以高效地在ListView中加载网络图片,同时保证应用的流畅性。同时,合理利用缓存和优化策略,可以...

    android ListView 加载网络图片

    在listview中显示网络图片,该类重写simpleadapter,让listview绑定该adapter

    android解析网络图片并显示在listview

    以上就是Android解析网络图片并显示在ListView中的主要知识点,这些技术和实践对于任何需要动态加载图片的Android应用来说都是至关重要的。在实际开发中,应根据项目需求和性能要求选择合适的方法和库。

    Listview显示网络图片demo--真正简单好用

    "Listview显示网络图片demo--真正简单好用"是一个针对这些问题的解决方案,它提供了一个优雅且高效的实现方式,保证了用户体验的流畅性。 首先,我们需要理解ListView的工作原理。ListView通过复用已创建的列表项来...

    Android Listview异步加载图片

    在Android开发中,ListView是常用的数据展示控件,它能够高效地显示大量数据。然而,当ListView中的每个项都包含图片时,如果直接在主线程中加载图片,会导致UI卡顿,用户体验下降。为了解决这个问题,我们需要实现...

    listview加载网络图片的例子

    `这一行代码负责加载并显示网络图片。 当然,除了Picasso,还有其他如Glide、Fresco等优秀的图片加载库,它们都有各自的特点和优势。例如,Glide以其流畅的滚动和自动管理内存而受到欢迎,Fresco则提供了更高级的...

    android listView 异步加载图片

    这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...

    android listview从mysql加载数据和图片

    本示例"android listview从mysql加载数据和图片"将介绍如何从MySQL数据库获取数据,并在ListView中显示这些数据以及对应的图片。这个过程涉及到Web服务端、Android客户端以及MySQL数据库的交互。 首先,我们需要在...

    Android高级应用源码-listview获取网络图片缓存优化.zip

    在Android开发中,ListView是展示大量数据常用的组件,但直接加载网络图片会遇到性能问题,如界面卡顿、内存溢出等。这个"Android高级应用源码-listview获取网络图片缓存优化.zip"是一个示例项目,旨在解决这些问题...

    android listView图片异步加载(拖动时不加载,双缓存)

    通过以上步骤,我们可以实现一个高效的图片异步加载方案,确保ListView在滚动时保持流畅,同时充分利用双缓存策略降低网络请求频率,提升应用性能。在实际项目中,可以根据需求选择合适的第三方库,或者自定义实现以...

    android 中ListView下载图片

    这些库提供了方便的API,可以轻松地在ListView中加载网络图片或本地资源图片。以Glide为例,使用Glide可以简化代码,提高效率: ```java Glide.with(context) .load(url) .into(imageView); ``` 2. **使用...

    Android listview实现图片的异步加载Demo.zip

    这个"Android listview实现图片的异步加载Demo.zip"就是一个示例,它展示了如何在ListView中高效地加载网络或本地的图片。 首先,我们需要理解异步加载的基本原理。在Android中,我们通常使用AsyncTask或者Handler/...

Global site tag (gtag.js) - Google Analytics