zoukankan      html  css  js  c++  java
  • ImageLoader配合ImageSwitcher的使用

    先在MyApplication中初始化ImageLoader

    initImageLoader(getApplicationContext());
       /**
        * 初始化ImageLoader
        * 如果你经常出现oom
        * 减少配置的线程池的大小(.threadPoolSize(...)),建议1~5
        * 配置中使用.diskCacheExtraOptions(480, 320, null)
        * @param context
        */
        public static void initImageLoader(Context context) {
            // This configuration tuning is custom. You can tune every option, you may tune some of them, 
            // or you can create default configuration by
            // ImageLoaderConfiguration.createDefault(this);
            // method.
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                    .threadPriority(Thread.NORM_PRIORITY - 1)
                    .threadPoolSize(5)
                    .denyCacheImageMultipleSizesInMemory()
                    .discCacheFileNameGenerator(new Md5FileNameGenerator())
                    .discCacheSize(100 * 1024 * 1024)
                    .tasksProcessingOrder(QueueProcessingType.LIFO)
                    //.enableLogging() // Not necessary in common
                    .build();
            // Initialize ImageLoader with configuration.
            MyImageLoader.getInstance().init(config);
        }

    再在BaseActivity中新建一个imageLoader 和设置参数

    protected MyImageLoader imageLoader = MyImageLoader.getInstance();
    /**
         * 如果你经常出现oom
         * 禁用在内存中缓存cacheInMemory(false),
         * 在显示选项中使用 .bitmapConfig(Bitmap.Config.RGB_565) . RGB_565模式消耗的内存比ARGB_8888模式少两倍.
         * 配置中使用 .memoryCache(newWeakMemoryCache()) 或者完全禁用在内存中缓存(don't call .cacheInMemory()).
         * 在显示选项中使用.imageScaleType(ImageScaleType.EXACTLY) 或 .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
         * 一定要对ImageLoaderConfiguration进行初始化,否则会报错
         * 开启缓存后默认会缓存到外置SD卡如下地址(/sdcard/Android/data/[package_name]/cache).如果外置SD卡不存在,会缓存到手机. 缓存到Sd卡需要在AndroidManifest.xml文件中进行配置WRITE_EXTERNAL_STORAGE
         */
        protected DisplayImageOptions options = new DisplayImageOptions.Builder()
        //.resetViewBeforeLoading()
        //.showImageOnLoading(R.drawable.ic_stub) //加载中显示的图片 
        //.showImageOnFail(R.drawable.ic_error)  //加载失败显示的图片
        //.cacheInMemory()
        .cacheOnDisc()    // 设置下载的图片是否缓存在SD卡中   //缓存在/mnt/shell/emulated/0/Android/data/com.sdmc.hotel.ollauncher/cache/uil-images
        .imageScaleType(ImageScaleType.IN_SAMPLE_INT)//设置图片以如何的编码方式显示(图像将被二次采样的整数倍)
        .bitmapConfig(Bitmap.Config.RGB_565)   //16 R占5位 G占6位 B占5位 没有透明度(A)
        //.displayer(new FadeInBitmapDisplayer(500))//设置图片渐显的时间
        .build();

    在要使用的activity中使用方式

    imageLoader.displayImage(this, path, (ImageView) mImageSwitcher.getCurrentView(), 
                            options, mImageLoadingListener);
    imageLoader.loadImage(this, path, 
                            options, mImageLoadingListener);

    还要加一个监听器

        /**
         * 把imageUri加载成bitmap之后就会触动监听,
         * 然后把加载出来的bitmap加入到SparseArray<SoftReference<Bitmap>>
         * before imageUri=file:///data/user/0/com.sdmc.hotel.ollauncher/files/cloud/public/upload/picture/1441178486.jpg
         * after path=/public/upload/picture/1441178486.jpg;
         * hashCode=-1524414597
         */
        private SimpleImageLoadingListener mImageLoadingListener = new SimpleImageLoadingListener() {
            
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                String path = imageUri.substring(imageUri.indexOf(Configs.getHotelProj(mContext)) 
                        + Configs.getHotelProj(mContext).length());
                log("before imageUri="+imageUri+"; getHotelProj"+Configs.getHotelProj(mContext));
                log("after path="+path+";hashCode="+path.hashCode());
                mLoadedImages.append(path.hashCode(), new SoftReference<Bitmap>(loadedImage));
            }
        };

    以及一个软引用的SparseArray

    //SparseArray替代HashMap,SoftReference软连接
    private SparseArray<SoftReference<Bitmap>> mLoadedImages = new SparseArray<SoftReference<Bitmap>>();

    还有就是MyImageLoader 的类

    /**
     * Copyright(c) 2003-2013 Shenzhen SDMC Technology Co.,LTD 
     * All Rights Reserved.
     * 
     * Filename : MyImageLoader.java
     * Author : wuxiaodi
     * Creation time : 下午2:01:58 - 2013-7-17
     * Description :
     */
    package com.sdmc.hotel.util;
    
    import java.io.File;
    
    import android.content.Context;
    import android.widget.ImageView;
    
    import com.nostra13.universalimageloader.core.DisplayImageOptions;
    import com.nostra13.universalimageloader.core.ImageLoader;
    import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
    import com.nostra13.universalimageloader.core.assist.ImageSize;
    
    /**
     * Just to cache images in our archive, so to use it when off-line.
     */
    public class MyImageLoader extends ImageLoader {
        private static MyImageLoader instance;
        
        public static MyImageLoader getInstance() {
            if (instance == null) {
                synchronized (MyImageLoader.class) {
                    if (instance == null) {
                        instance = new MyImageLoader();
                    }
                }
            }
            return instance;
        }
        
        protected MyImageLoader() {
            
        }
        
        public void displayImage(Context context, String path, ImageView imageView) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.displayImage(Configs.getServerAddress(context) + path, imageView);
            } else {
                super.displayImage(furi, imageView);
            }
        }
        
        public void displayImage(Context context, String path, ImageView imageView, DisplayImageOptions options) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.displayImage(Configs.getServerAddress(context) + path, imageView, options);
            } else {
                super.displayImage(furi, imageView, options);
            }
        }
        
        public void displayImage(Context context, String path, ImageView imageView, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.displayImage(Configs.getServerAddress(context) + path, imageView, listener);
            } else {
                super.displayImage(furi, imageView, listener);
            }
        }
        /**
         * displayImage()方法中,对ImageView对象使用的是Weak references,
         * 方便垃圾回收器回收ImageView对象,如果我们要加载固定大小的图片的时候,
         * 使用loadImage()方法需要传递一个ImageSize对象,而displayImage()方法会根据ImageView对象的
         * 测量值,或者android:layout_width and android:layout_height设定的值,
         * 或者android:maxWidth and/or android:maxHeight设定的值来裁剪图片
         * 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
         * @param context
         * @param path
         * @param imageView
         * @param options
         * @param listener
         */
        public void displayImage(Context context, String path, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
    //            log("furi1:"+Configs.getServerAddress(context) + path+";imageView"+imageView+";options"+options+";listener"+listener);
                super.displayImage(Configs.getServerAddress(context) + path, imageView, options, listener);
            } else {
                //furi2:file:///data/data/com.sdmc.hotel.ollauncher/files/cloud/public/upload/picture/1441178355.jpg;imageViewandroid.widget.;optionscom.nostra13.;listenercom.sdmc
    //            log("furi2:"+furi+";imageView"+imageView+";options"+options+";listener"+listener);
                super.displayImage(furi, imageView, options, listener);
            }
        }
        /**
         * displayImage更方便
         * 使用ImageLoader的loadImage()方法来加载网络图片
         * loadImage()是将图片对象回调到ImageLoadingListener接口的onLoadingComplete()方法中,
         * 需要我们手动去设置到ImageView上面
         * @param context
         * @param path
         * @param listener
         */
        public void loadImage(Context context, String path, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.loadImage(Configs.getServerAddress(context) + path, listener);
            } else {
                super.loadImage(furi, listener);
            }
        }
        /**
         * displayImage更方便
         * 如果我们要指定图片的大小该怎么办呢,这也好办,初始化一个ImageSize对象,指定图片的宽和高,代码如下
         * @param context
         * @param path
         * @param minImageSize  ImageSize mImageSize = new ImageSize(100, 100);  
         * @param listener
         */
        public void loadImage(Context context, String path, ImageSize minImageSize, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.loadImage(Configs.getServerAddress(context) + path, minImageSize, listener);
            } else {
                super.loadImage(furi, minImageSize, listener);
            }
        }
    
        public void loadImage(Context context, String path, DisplayImageOptions options, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.loadImage(Configs.getServerAddress(context) + path, options, listener);
            } else {
                super.loadImage(furi, options, listener);
            }
        }
    
        public void loadImage(Context context, String path, ImageSize targetImageSize, DisplayImageOptions options, ImageLoadingListener listener) {
            String furi = getLocalImage(context, path);
            if (furi == null) {
                super.loadImage(Configs.getServerAddress(context) + path, targetImageSize, options, listener);
            } else {
                super.loadImage(furi, targetImageSize, options, listener);
            }
        }
        
        private String getLocalImage(Context context, String path) {
            File imagefile = new File(Configs.getCacheDir(context) + path);
            if (imagefile.exists()) {
                return "file://" + imagefile.getAbsolutePath();
            } else {
                return null;
            }
        }
    //    private void log(String msg) {
    //        LogUtil.info(this.getClass(), this + ":" + msg,"i");
    //
    //    }
    }

    如果要配合ImageSwitcher 的话也很方便,先新建一个ImageSwitcher 

    private ImageSwitcher createImageSwitcher(JsonReader reader) {
            ImageSwitcherLayoutParams params = new Gson().fromJson(reader,
                    ImageSwitcherLayoutParams.class);
    
            mImageSwitcher = new ImageSwitcher(this);
            mImageSwitcher.setFactory(this);
    
            AlphaAnimation inAnim = new AlphaAnimation(0, 1);
            inAnim.setDuration(300);
            mImageSwitcher.setInAnimation(inAnim);
            AlphaAnimation outAnim = new AlphaAnimation(1, 0);
            outAnim.setDuration(400);
            mImageSwitcher.setOutAnimation(outAnim);
            AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(
                    params.width, params.height, params.x, params.y);
            mImageSwitcher.setLayoutParams(lp);
            return mImageSwitcher;
        }

    然后实现implements ViewFactory接口,重写makeView方法

    @Override
        public View makeView() {
            ImageView imageView = new ImageView(this);
            imageView.setScaleType(ScaleType.FIT_XY);
            imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
                    ImageSwitcher.LayoutParams.MATCH_PARENT, 
                    ImageSwitcher.LayoutParams.MATCH_PARENT));
            return imageView;
        }

    =============================================================================================================================================================================================================================================================================================================================================================================================

    DisplayImageOptions options = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.ic_stub) // 设置图片下载期间显示的图片
            .showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片
            .showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片
            .resetViewBeforeLoading(false)  // default 设置图片在加载前是否重置、复位
            .delayBeforeLoading(1000)  // 下载前的延迟时间
            .cacheInMemory(false) // default  设置下载的图片是否缓存在内存中
            .cacheOnDisk(false) // default  设置下载的图片是否缓存在SD卡中
            .preProcessor(...)
            .postProcessor(...)
            .extraForDownloader(...)
            .considerExifParams(false) // default
            .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示
            .bitmapConfig(Bitmap.Config.ARGB_8888) // default 设置图片的解码类型
            .decodingOptions(...)  // 图片的解码设置
            .displayer(new SimpleBitmapDisplayer()) // default  还可以设置圆角图片new RoundedBitmapDisplayer(20)
            .handler(new Handler()) // default
            .build();
    
    File cacheDir = StorageUtils.getCacheDirectory(context);  //缓存文件夹路径
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
            .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽
            .diskCacheExtraOptions(480, 800, null)  // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个 
            .taskExecutor(...)
            .taskExecutorForCachedImages(...)
            .threadPoolSize(3) // default  线程池内加载的数量
            .threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级
            .tasksProcessingOrder(QueueProcessingType.FIFO) // default
            .denyCacheImageMultipleSizesInMemory()
            .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现
            .memoryCacheSize(2 * 1024 * 1024)  // 内存缓存的最大值
            .memoryCacheSizePercentage(13) // default
            .diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定义缓存路径  
            .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值
            .diskCacheFileCount(100)  // 可以缓存的文件数量 
            // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密
            .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) 
            .imageDownloader(new BaseImageDownloader(context)) // default
            .imageDecoder(new BaseImageDecoder()) // default
            .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
            .writeDebugLogs() // 打印debug log
            .build(); //开始构建

    权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission></uses-permission>
  • 相关阅读:
    Lock接口与等待唤醒机制
    线程同步(线程安全处理Synchronized)与死锁
    关于线程安全的例子(电影票出售)
    线程池
    多线程
    commons-IO工具包
    打印流
    关于web的安全问题
    防止手机页面软键盘调出时布局被挤压
    css3新特性归总笔记
  • 原文地址:https://www.cnblogs.com/lipeineng/p/5286696.html
Copyright © 2011-2022 走看看