前言

话说这universalimageloader载入图片对搞过2年安卓程序都是用烂了再熟悉只是了。就是安卓新手也是百度就会有一大堆东西出来,今天为什么这里还要讲使用universalimageloader呢。一是由于这个东西确实是一个非常不错的东西。第二让我们用imageloader来学习 载入圆形圆角图片。

三呢以后项目中可能用到了直接copy。
GITHUB上的下载路径为:https://github.com/nostra13/Android-Universal-Image-Loader ,下载最新的库文件,而且导入到项目的LIB下便能够使用。该库以及DEMO本地下载链接:下载地址
效果图:
图片效果

universalimageloader的简介:

处理流程

看了再也不操心会oom。然后也不须要去考率3级缓存,我们能够看出。UIL载入图片的一般流程是先推断内存中是否有相应的Bitmap。再推断磁盘(disk)中是否有,假设没有就从网络中载入。最后依据原先在UIL中的配置推断是否须要缓存Bitmap到内存或磁盘中。Bitmap载入完后,就对它进行解析,然后显示到特定的ImageView中。

universalimageloader的使用

第一步:增加库
1 .下载jar包放在libs目录中
2 .Maven dependency:  
<dependency>
    <groupId>com.nostra13.universalimageloader</groupId>
    <artifactId>universal-image-loader</artifactId>
    <version>1.9.2</version>
</dependency>

3 .Gradle dependency:

compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.2'
第二步:配置清单文件权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
第三步:配置ImageLoaderConfiguration參数

在应用中配置ImageLoaderConfiguration參数(仅仅能配置一次,如多次配置。则默认第一次的配置參数)

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
         .discCache(new LimitedAgeDiscCache(cacheDir, 7 * 24 * 60 * 60))// 自己定义缓存路径,7天后自己主动清除缓存
        .writeDebugLogs() // 打印debug log
        .build(); //開始构建  

Configuration的參数就算是配好了,当然了怎么配置随你的便。可是必须在初始化曾经必须要配置,为了不进行多次配置,我们都把它放在application里面的。

第四步:初始化imageLoder

ImageLoader.getInstance().init(config); // 初始化

第五步 :imageLoder显示option的配置
 options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_stub)//缓冲过程中图片
                .showImageForEmptyUri(R.mipmap.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(R.drawable.ic_error)// 设置图片载入或解码过程中错误发生显示的图片
                .cacheInMemory(true)//缓存道内存
                .cacheOnDisc(true)//缓存到硬盘
                .bitmapConfig(Bitmap.Config.ARGB_8888)   //设置图片的解码类型

                .build();

上段代码我们设置了载入显示过程中的图片处理。和缓存处理。

然后使用ImageLoader.getInstance().displayImage(url,imagview,options);
我们通过设置 .displayer属性来产生各种图片形状。

然后载入本地图片资源的代码:

import android.widget.ImageView;
import com.nostra13.universalimageloader.core.ImageLoader;
/**
 * 异步载入本地图片工具类
 * 
 * 
 */
public class LoadLocalImageUtil {
    private LoadLocalImageUtil() {
    }
    private static LoadLocalImageUtil instance = null;

    public static synchronized LoadLocalImageUtil getInstance() {
        if (instance == null) {
            instance = new LoadLocalImageUtil();
        }
        return instance;
    }
    /**
     * 从内存卡中异步载入本地图片
     * 
     * @param uri
     * @param imageView
     */
    public void displayFromSDCard(String uri, ImageView imageView) {
        // String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
        ImageLoader.getInstance().displayImage("file://" + uri, imageView);
    }

    /**
     * 从assets目录中异步载入图片
     * 
     * @param imageName
     *            图片名称,带后缀的,比如:1.png
     * @param imageView
     */
    public void dispalyFromAssets(String imageName, ImageView imageView) {
        // String imageUri = "assets://image.png"; // from assets
        ImageLoader.getInstance().displayImage("assets://" + imageName,
                imageView);
    }
    /**
     * 从drawable中异步载入本地图片
     * 
     * @param imageId
     * @param imageView
     */
    public void displayFromDrawable(int imageId, ImageView imageView) {
        // String imageUri = "drawable://" + R.drawable.image; // from drawables
        // (only images, non-9patch)
        ImageLoader.getInstance().displayImage("drawable://" + imageId,
                imageView);
    }
    /**
     * 从内容提提供者中抓取图片
     */
    public void displayFromContent(String uri, ImageView imageView) {
        // String imageUri = "content://media/external/audio/albumart/13"; //
        // from content provider
        ImageLoader.getInstance().displayImage("content://" + uri, imageView);
    }
}

universalimageloader载入圆形图片

所以呢我们这里来了一个自己定义圆形显示控件:

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;

/**
 * Created by zengyu on 2016/3/2.
 */

public class Displayer extends RoundedBitmapDisplayer {
    public Displayer(int cornerRadiusPixels) {
        super(cornerRadiusPixels);
    }
    // 显示位图
    @Override
    public void display(Bitmap bitmap, ImageAware imageAware,
                        LoadedFrom loadedFrom) {
        imageAware.setImageDrawable(new CircleDrawable(bitmap, margin));
    }

    public static class CircleDrawable extends Drawable {
        private final int margin;
        private final RectF mRect = new RectF();
        private final BitmapShader bitmapShader;
        private final Paint paint;
        private RectF mBitmapRect;

        public CircleDrawable(Bitmap bitmap, int margin) {
            this.margin = 0;
            // 创建着色器
            bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
                    Shader.TileMode.CLAMP);
            mBitmapRect = new RectF(margin, margin, bitmap.getWidth() - margin,
                    bitmap.getHeight() - margin);
            // 设置画笔
            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setShader(bitmapShader);
        }

        // 画圆,覆盖原来的位图
        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mRect.set(margin, margin, bounds.width() - margin, bounds.height()
                    - margin);

            // 调整位图,设置该矩阵,转换映射源矩形和目的矩形
            Matrix shaderMatrix = new Matrix();
            shaderMatrix.setRectToRect(mBitmapRect, mRect,
                    Matrix.ScaleToFit.FILL);
            // 设置着色器矩阵
            bitmapShader.setLocalMatrix(shaderMatrix);
        }

        // 画出其边界(通过设置的setBounds)
        @Override
        public void draw(Canvas canvas) {
            canvas.drawRoundRect(mRect, mRect.width()/2 , mRect.height()/2,
                    paint);
        }

        /**
         * 返回此绘制对象的不透明度/透明度 ,返回的值是抽象的格式常数的PixelFormat之中的一个:未知,半透明,透明或不透明
         * */
        @Override
        public int getOpacity() {
            // 半透明
            return PixelFormat.TRANSLUCENT;
        }

        // 设置透明度
        @Override
        public void setAlpha(int alpha) {
            paint.setAlpha(alpha);
        }

        // 彩色滤光片(通过设置setColorFilter)
        @Override
        public void setColorFilter(ColorFilter cf) {
            paint.setColorFilter(cf);
        }
    }
}

好了主要的使用都讲完了。

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class MainActivity extends AppCompatActivity {
    @InjectView(R.id.iv_normal)
    ImageView ivNormal;
    @InjectView(R.id.iv_fillet)
    ImageView ivFillet;
    @InjectView(R.id.iv_circular)
    ImageView ivCircular;
    private  DisplayImageOptions options1,options2,options3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        //原图显示
        options1 = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_stub)
                .showImageForEmptyUri(R.mipmap.ic_launcher)
                .showImageOnFail(R.drawable.ic_error)
                .cacheInMemory(true)
                .cacheOnDisc(true)
                .bitmapConfig(Bitmap.Config.ARGB_8888)   //设置图片的解码类型
                .build();
        //圆角图片
        options2 = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_stub)
                .showImageForEmptyUri(R.mipmap.ic_launcher)
                .showImageOnFail(R.drawable.ic_error)
                .cacheInMemory(true)
                .cacheOnDisc(true)
                .bitmapConfig(Bitmap.Config.ARGB_8888)   //设置图片的解码类型
                .displayer(new RoundedBitmapDisplayer(20))
                .build();
        //圆形图片
        options3 = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_stub)
                .showImageForEmptyUri(R.mipmap.ic_launcher)
                .showImageOnFail(R.drawable.ic_error)
                .cacheInMemory(true)
                .cacheOnDisc(true)
                .bitmapConfig(Bitmap.Config.ARGB_8888)   //设置图片的解码类型
                .displayer(new Displayer(0))
                .build();
        ImageLoader.getInstance().displayImage("//img-my.csdn.net/uploads/201309/01/1378037193_1286.jpg",ivNormal,options1);
        ImageLoader.getInstance().displayImage("//img-my.csdn.net/uploads/201309/01/1378037193_1286.jpg",ivFillet,options2);
       ImageLoader.getInstance().displayImage("//img-my.csdn.net/uploads/201309/01/1378037193_1286.jpg",ivCircular,options3);
    }
}

图片效果

四、注意事项

1、ImageLoader是依据ImageView的height,width确定图片的宽高
2、一定要对ImageLoaderConfiguration进行初始化,否则会报错
3、开启缓存后默认会缓存到外置SD卡
4、清除缓存

 public void onClearMemoryClick(View view) {
        ImageLoader.getInstance().clearMemoryCache();  // 清除内存缓存
    }
    public void onClearDiskClick(View view) {
        ImageLoader.getInstance().clearDiskCache();  // 清除本地缓存
    }

近期技术群里面发现面试的题目越来越有深度了,然后感觉工作也是越来越难找咯。是该继续学习新东西了。

到了com.nostra13.universalimageloader:universal-image-loader:1.9.3里面就有CircleBitmapDisplayer()了,再也不须要自己去写了,当然你也能够使用universal-image-loader-1.9.5.jar直接网络载入圆形图片。谢谢大家的指证。