zoukankan      html  css  js  c++  java
  • ListView异步加载图片的解决办法

    (转自:http://www.iteye.com/topic/1123524

    关于ListView异步加载图片有很多方式,也有很多方法可以解决图片错位的现象,看完他们写的代码,多半是基于回调的方式,比如这位:http://www.iteye.com/topic/685986 
    他解决错位的方式很巧妙: 
    ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl); 
    在构造适配器是传入ListView的引用,由唯一的TAG来找显示的ImageView; 
    还有这位:http://www.iteye.com/topic/1118828 
    为了提升用户的体验效果,使用了线程等待。 

    下面分享我的方法: 
    也没有考虑到加载数量多的图片,和大图片,这些用户可以根据自己需要用ThumbnailUtils类进行处理,关于一次启动几十个线程的问题,我感觉没有担心的必要,感觉分页就可以解决。 
    下面贴代码(可以处理加载网络图片和本地图片): 

     
    import java.io.IOException;  
    import java.io.InputStream;  
    import java.lang.ref.SoftReference;  
    import java.net.MalformedURLException;  
    import java.net.URL;  
    import java.util.HashMap;  
      
    import android.graphics.Bitmap;  
    import android.graphics.BitmapFactory;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.widget.ImageView;  
      
    /** 
     * 图片异步加载工具类 
     *  
     * @version V1.0 
     */  
    public class AsynImageLoader {  
      
        // 图片软引用  
        private HashMap<String, SoftReference<Bitmap>> imageCache;  
        // 显示图片的ImageView  
        private HashMap<String, ImageView> imageViews;  
      
        public AsynImageLoader() {// 构造  
            imageCache = new HashMap<String, SoftReference<Bitmap>>();  
            imageViews = new HashMap<String, ImageView>();  
        }  
      
        /** 
         * 从网络上获取图片 
         *  
         * @param imageView 
         *            显示图片的ImageView 
         * @param imageUrl 
         *            图片的地址 
         * @return 图片 
         */  
        public Bitmap loadDrawableFromNet(final ImageView imageView,  
                final String imageUrl) {  
            return loadDrawable(imageView, imageUrl, new LoadCallBack() {  
                public Bitmap load(String uri) {  
                    return loadImageFromNet(uri);  
                }  
            });  
        }  
      
        /** 
         * 从本地获取图片 
         *  
         * @param imageView 
         *            显示图片的ImageView 
         * @param imageUrl 
         *            图片的路径 
         * @return 图片 
         */  
        public Bitmap loadDrawableFromLocal(final ImageView imageView,  
                final String imageUrl) {  
            return loadDrawable(imageView, imageUrl, new LoadCallBack() {  
                public Bitmap load(String uri) {  
                    return loadImageFromLocal(uri);  
                }  
            });  
        }  
      
        /** 
         * 获取图片 
         *  
         * @param imageView 
         *            显示图片的ImageView 
         * @param imageUrl 
         *            图片路径或网络地址 
         * @param load 
         *            回调方法 加载本地图片或者加载网络图片 
         * @return 
         */  
        private Bitmap loadDrawable(final ImageView imageView,  
                final String imageUrl, final LoadCallBack load) {  
      
            // 判断软引用里是否有图片  
            if (imageCache.containsKey(imageUrl)) {  
                SoftReference<Bitmap> softReference = imageCache.get(imageUrl);  
                Bitmap bitmap = softReference.get();  
                if (bitmap != null) {  
                    return bitmap;// 有则返回  
                }  
            }  
      
            // 将为添加到图片显示集合的 ImageViwe 加入到集合  
            if (!imageViews.containsKey(imageUrl)) {  
                imageViews.put(imageUrl, imageView);  
            }  
      
            final Handler handler = new Handler() {  
                public void handleMessage(Message message) {  
                    imageViews.get(imageUrl).setImageBitmap((Bitmap) message.obj);  
                }  
            };  
      
            //启动线程获取图片  
            new Thread() {  
                public void run() {  
                    Bitmap bitmap = load.load(imageUrl);//执行回调  
                    imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));  
                    Message message = handler.obtainMessage(0, bitmap);  
                    handler.sendMessage(message);  
                }  
            }.start();  
            return null;  
        }  
      
        private interface LoadCallBack {  
            public Bitmap load(String uri);  
        }  
      
        /** 
         * 从网络加载图片 
         *  
         * @param url 
         * @return 
         */  
        public Bitmap loadImageFromNet(String url) {  
            URL m;  
            InputStream i = null;  
            try {  
                m = new URL(url);  
                i = (InputStream) m.getContent();  
            } catch (MalformedURLException e1) {  
                e1.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            return BitmapFactory.decodeStream(i);  
        }  
      
        /** 
         * 从本地加载图片 
         *  
         * @param path 
         * @return 
         */  
        public Bitmap loadImageFromLocal(String path) {  
            return BitmapFactory.decodeFile(path);  
        }  
    }  


    这个处理方式没有用到回调,没让ListView传入Adapter,没让Adapter里的代码显得那么臃肿,下面贴两行调用: 

    Bitmap cachedImage = loader.loadDrawableFromNet(item.imageView,url);  
    item.setImageBitmap(cachedImage);  



    核心的思想就是在加载类里面做一个集合来存放显示的ImageView 

  • 相关阅读:
    优化网站设计(四):对资源启用压缩
    优化网站设计(三):对资源添加缓存控制
    旧貌换新颜 华为助力甲壳虫科技打造智慧环卫
    软件开发项目云端All-In-One体验
    码农进“城”之路---我从机械男转入软件开发行业的亲身经历
    如何选择版本控制系统之三---代码托管操作
    推荐五款Android 应用的自动化测试工具
    移动应用/APP的测试流程及方法
    老程序员总结的16条经验教训
    30多个Android 开发者工具 带你开发带你飞
  • 原文地址:https://www.cnblogs.com/imlucky/p/2616317.html
Copyright © 2011-2022 走看看