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>
原文地址:https://www.cnblogs.com/lipeineng/p/5286696.html