zoukankan      html  css  js  c++  java
  • 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)方法来实现的

    Java代码 复制代码 收藏代码
    1. /**  
    2.      * @see android.widget.Adapter#getView(int, View, ViewGroup)  
    3.      */  
    4.     public View getView(int position, View convertView, ViewGroup parent) {   
    5.         return createViewFromResource(position, convertView, parent, mResource);   
    6.     }  
    /**
         * @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代码 复制代码 收藏代码
    1. private View createViewFromResource(int position, View convertView,   
    2.             ViewGroup parent, int resource) {   
    3.         View v;   
    4.         if (convertView == null) {   
    5.             v = mInflater.inflate(resource, parent, false);   
    6.   
    7.             final int[] to = mTo;   
    8.             final int count = to.length;   
    9.             final View[] holder = new View[count];   
    10.   
    11.             for (int i = 0; i < count; i++) {   
    12.                 holder[i] = v.findViewById(to[i]);   
    13.             }   
    14.   
    15.             v.setTag(holder);   
    16.         } else {   
    17.             v = convertView;   
    18.         }   
    19.   
    20.         bindView(position, v);   
    21.   
    22.         return v;   
    23.     }  
    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代码 复制代码 收藏代码
    1. private void bindView(int position, View view) {   
    2.         final Map dataSet = mData.get(position);   
    3.         if (dataSet == null) {   
    4.             return;   
    5.         }   
    6.   
    7.         final ViewBinder binder = mViewBinder;   
    8.         final View[] holder = (View[]) view.getTag();   
    9.         final String[] from = mFrom;   
    10.         final int[] to = mTo;   
    11.         final int count = to.length;   
    12.   
    13.         for (int i = 0; i < count; i++) {   
    14.             final View v = holder[i];   
    15.             if (v != null) {   
    16.                 final Object data = dataSet.get(from[i]);   
    17.                 String text = data == null ? "" : data.toString();   
    18.                 if (text == null) {   
    19.                     text = "";   
    20.                 }   
    21.   
    22.                 boolean bound = false;   
    23.                 if (binder != null) {   
    24.                     bound = binder.setViewValue(v, data, text);   
    25.                 }   
    26.   
    27.                 if (!bound) {   
    28.                     if (v instanceof Checkable) {   
    29.                         if (data instanceof Boolean) {   
    30.                             ((Checkable) v).setChecked((Boolean) data);   
    31.                         } else {   
    32.                             throw new IllegalStateException(v.getClass().getName() +   
    33.                                     " should be bound to a Boolean, not a " + data.getClass());   
    34.                         }   
    35.                     } else if (v instanceof TextView) {   
    36.                         // Note: keep the instanceof TextView check at the bottom of these   
    37.                         // ifs since a lot of views are TextViews (e.g. CheckBoxes).   
    38.                         setViewText((TextView) v, text);   
    39.                     } else if (v instanceof ImageView) {   
    40.                                if (data instanceof Integer) {   
    41.                             setViewImage((ImageView) v, (Integer) data);                               
    42.                         } else {   
    43.                             setViewImage((ImageView) v, text);   
    44.                         }   
    45.                     } else {   
    46.                         throw new IllegalStateException(v.getClass().getName() + " is not a " +   
    47.                                 " view that can be bounds by this SimpleAdapter");   
    48.                     }   
    49.                 }   
    50.             }   
    51.         }   
    52.     }  
    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代码 复制代码 收藏代码
    1. public void setViewImage(ImageView v, int value) {   
    2.     v.setImageResource(value);   
    3. }   
    4.   
    5.   
    6. public void setViewImage(ImageView v, String value) {   
    7.     try {   
    8.         v.setImageResource(Integer.parseInt(value));   
    9.     } catch (NumberFormatException nfe) {   
    10.         v.setImageURI(Uri.parse(value));   
    11.     }   
    12. }  
        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代码 复制代码 收藏代码
    1. public void setViewImage(ImageView v, String value) {   
    2.         Bitmap bitmap = WebImageBuilder.returnBitMap(value);   
    3.         ((ImageView) v).setImageBitmap(bitmap);   
    4.     }  
    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

  • 相关阅读:
    spring对返回结果的拦截器
    mysql 8.0.15 的my.ini 配置
    利用apache 的PropertyUtilsBean 实现map和pojo相互转换
    给数字补0
    清空文件的内容 和 统计文件的大小的命令
    MySQL的replace函数的用法
    PHP Warning: Module 'modulename' already loaded in Unknown on line 0 的解决方法
    技术总监Sycx的故事
    编译PHP扩展的通用方法
    给大家推荐几本经典技术书籍
  • 原文地址:https://www.cnblogs.com/xiaoran1129/p/3120063.html
Copyright © 2011-2022 走看看