Home

Awesome

前言

初识Glide

##Glide配置 1、 在build.gradle中添加依赖:

dependencies {
  compile 'com.github.bumptech.glide:glide:3.7.0'
  compile 'com.android.support:support-v4:19.1.0'
}

Or Maven:

<dependency>
  <groupId>com.github.bumptech.glide</groupId>
  <artifactId>glide</artifactId>
  <version>3.7.0</version>
</dependency>
<dependency>
  <groupId>com.google.android</groupId>
  <artifactId>support-v4</artifactId>
  <version>r7</version>
</dependency>

2、混淆

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

3、权限 如果是联网获取图片或者本地存储需要添加以下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

##Glide基本使用 Glide使用一个流接口(Fluent Interface)。用Glide完成一个完整的图片加载功能请求,需要向其构造器中至少传入3个参数,分别是:

example:

ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
String internetUrl = "http://i.imgur.com/DvpvklR.png";

Glide
    .with(context)
    .load(internetUrl)
    .into(targetImageView);

##Compatibility

##常用API

更多Glide详细介绍可以看Glide官网以及Glide教程系列文章

如何封装

明白了为什么封装以及基本原理,接下来我们就要开工,大干一场。

先看一下本人封装后的基本使用样式:

ImageLoader.with(this)
	.url("http://img.yxbao.com/news/image/201703/13/7bda462477.gif")
	.placeHolder(R.mipmap.ic_launcher,false)
	.rectRoundCorner(30, R.color.colorPrimary)
	.blur(40)
	.into(iv_round);

更多属性我们后再详细讲解使用,主要先来看看具体的封装。

先看一下uml:

这里写图片描述

使用者只需要关心ImageLoader就好了,就算里面封装的库更换、更新也没关系,因为对外的接口是不变的。实际操作中是由实现了ILoader的具体类去操作的,这里我们只封装了GlideLoader,其实所有操作都是由ImageLoader下发指令,由GlideLoader具体去实现的。这里如果想封装别的第三方库,只需要实现ILoader自己去完成里面的方法。

##初始化

	public static int CACHE_IMAGE_SIZE = 250;

    public static void init(final Context context) {
        init(context, CACHE_IMAGE_SIZE);
    }

    public static void init(final Context context, int cacheSizeInM) {
        init(context, cacheSizeInM, MemoryCategory.NORMAL);
    }

    public static void init(final Context context, int cacheSizeInM, MemoryCategory memoryCategory) {
        init(context, cacheSizeInM, memoryCategory, true);
    }

    /**
     * @param context        上下文
     * @param cacheSizeInM   Glide默认磁盘缓存最大容量250MB
     * @param memoryCategory 调整内存缓存的大小 LOW(0.5f) / NORMAL(1f) / HIGH(1.5f);
     * @param isInternalCD   true 磁盘缓存到应用的内部目录 / false 磁盘缓存到外部存
     */
    public static void init(final Context context, int cacheSizeInM, MemoryCategory memoryCategory, boolean isInternalCD) {
        ImageLoader.context = context;
        GlobalConfig.init(context, cacheSizeInM, memoryCategory, isInternalCD);
    }

从这里可以看出我们提供了四个构造器,这里注释详细说明了所有参数的用法及意义。

除了初始化,我们还需要在Application中重写以下方法:

	@Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
		// 程序在内存清理的时候执行
        ImageLoader.trimMemory(level);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
	    // 低内存的时候执行
        ImageLoader.clearAllMemoryCaches();
    }

上面这两个方法会在下面ImageLoader中介绍到。

##你所关心的类--ImageLoader ImageLoader是封装好所有的方法供用户使用的,让我们看看都有什么方法:

##图片的各种设置信息--SingleConfig 我们所设置图片的所有属性都写在这个类里面。下面我们详细的看一下:

github项目地址

##中转站--GlideLoader GlideLoader实现ILoader接口。在使用的时候我们虽然不用关心这个类,但是了解一下主要做了什么功能还是不错的。

public class GlideLoader implements ILoader {

    /**
     * @param context        上下文
     * @param cacheSizeInM   Glide默认磁盘缓存最大容量250MB
     * @param memoryCategory 调整内存缓存的大小 LOW(0.5f) / NORMAL(1f) / HIGH(1.5f);
     * @param isInternalCD   true 磁盘缓存到应用的内部目录 / false 磁盘缓存到外部存
     */
    @Override
    public void init(Context context, int cacheSizeInM, MemoryCategory memoryCategory, boolean isInternalCD) {
        Glide.get(context).setMemoryCategory(memoryCategory); //如果在应用当中想要调整内存缓存的大小,开发者可以通过如下方式:
        GlideBuilder builder = new GlideBuilder(context);
        if (isInternalCD) {
            builder.setDiskCache(new InternalCacheDiskCacheFactory(context, cacheSizeInM * 1024 * 1024));
        } else {
            builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, cacheSizeInM * 1024 * 1024));
        }
    }

    @Override
    public void request(final SingleConfig config) {
        RequestManager requestManager = Glide.with(config.getContext());
        DrawableTypeRequest request = getDrawableTypeRequest(config, requestManager);

        if (config.isAsBitmap()) {
            SimpleTarget target = new SimpleTarget<Bitmap>(config.getWidth(), config.getHeight()) {
                @Override
                public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
                    config.getBitmapListener().onSuccess(bitmap);
                }
            };

            setShapeModeAndBlur(config, request);

            if (config.getDiskCacheStrategy() != null) {
                request.diskCacheStrategy(config.getDiskCacheStrategy());
                Logger.e("config.getDiskCacheStrategy() :  " + config.getDiskCacheStrategy());
            }

            request.asBitmap().into(target);

        } else {

            if (request == null) {
                return;
            }

            if (MyUtil.shouldSetPlaceHolder(config)) {
                request.placeholder(config.getPlaceHolderResId());
            }

            int scaleMode = config.getScaleMode();

            switch (scaleMode) {
                case ScaleMode.CENTER_CROP:
                    request.centerCrop();
                    break;
                case ScaleMode.FIT_CENTER:
                    request.fitCenter();
                    break;
                default:
                    request.fitCenter();
                    break;
            }

            // TODO: 2017/4/21 设置图片滤镜(目前只有高斯)
            setShapeModeAndBlur(config, request);

            //设置缩略图
            if (config.getThumbnail() != 0) {
                request.thumbnail(config.getThumbnail());
            }

            //设置图片加载的分辨 sp
            if (config.getoWidth() != 0 && config.getoHeight() != 0) {
                request.override(config.getoWidth(), config.getoHeight());
                Logger.e("设置图片加载的分辨 : " + config.getoWidth() + "   " + config.getoHeight());
            }

            //是否跳过磁盘存储
            if (config.getDiskCacheStrategy() != null) {
                request.diskCacheStrategy(config.getDiskCacheStrategy());
                Logger.e("config.getDiskCacheStrategy() :  " + config.getDiskCacheStrategy());
            }

            //设置图片加载动画
            setAnimator(config, request);

            //设置图片加载优先级
            setPriority(config, request);

            if (config.getErrorResId() > 0) {
                request.error(config.getErrorResId());
            }

            if (config.getTarget() instanceof ImageView) {
                request.into((ImageView) config.getTarget());

                Logger.e("config.getTarget()" + config.getTarget().getMeasuredWidth());
            }
        }

    }

    /**
     * 设置加载优先级
     *
     * @param config
     * @param request
     */
    private void setPriority(SingleConfig config, DrawableTypeRequest request) {
        switch (config.getPriority()) {
            case PriorityMode.PRIORITY_LOW:
                request.priority(Priority.LOW);
                break;
            case PriorityMode.PRIORITY_NORMAL:
                request.priority(Priority.NORMAL);
                break;
            case PriorityMode.PRIORITY_HIGH:
                request.priority(Priority.HIGH);
                break;
            case PriorityMode.PRIORITY_IMMEDIATE:
                request.priority(Priority.IMMEDIATE);
                break;
            default:
                request.priority(Priority.IMMEDIATE);
                break;
        }
    }

    /**
     * 设置加载进入动画
     *
     * @param config
     * @param request
     */
    private void setAnimator(SingleConfig config, DrawableTypeRequest request) {
        if (config.getAnimationType() == AnimationMode.ANIMATIONID) {
            request.animate(config.getAnimationId());
        } else if (config.getAnimationType() == AnimationMode.ANIMATOR) {
            request.animate(config.getAnimator());
        } else if (config.getAnimationType() == AnimationMode.ANIMATION) {
            request.animate(config.getAnimation());
        }
    }

    @Nullable
    private DrawableTypeRequest getDrawableTypeRequest(SingleConfig config, RequestManager requestManager) {
        DrawableTypeRequest request = null;
        if (!TextUtils.isEmpty(config.getUrl())) {
            request = requestManager.load(MyUtil.appendUrl(config.getUrl()));
        } else if (!TextUtils.isEmpty(config.getFilePath())) {
            request = requestManager.load(MyUtil.appendUrl(config.getFilePath()));
        } else if (!TextUtils.isEmpty(config.getContentProvider())) {
            request = requestManager.loadFromMediaStore(Uri.parse(config.getContentProvider()));
        } else if (config.getResId() > 0) {
            request = requestManager.load(config.getResId());
        }
        return request;
    }

    /**
     * 设置图片滤镜和形状
     *
     * @param config
     * @param request
     */
    private void setShapeModeAndBlur(SingleConfig config, DrawableTypeRequest request) {
        int shapeMode = config.getShapeMode();
        Transformation[] transformation = new Transformation[3];
        if (config.isNeedBlur()) {
           // transformation[0] = new BlurTransformation(config.getContext(), config.getBlurRadius());
            transformation[0] = new BrightnessFilterTransformation(config.getContext(), 0.5f);
            //transformation[0] =new GrayscaleTransformation(config.getContext()); 黑白效果
        }

        if(config.isNeedFilteColor()){
            transformation[2] = new ColorFilterTransformation(config.getContext(), config.getFilteColor());
        }

        switch (shapeMode) {
            case ShapeMode.RECT:

                break;
            case ShapeMode.RECT_ROUND:
                transformation[1] = new RoundedCornersTransformation
                        (config.getContext(), config.getRectRoundRadius(), 0, RoundedCornersTransformation.CornerType.ALL);

                break;
            case ShapeMode.OVAL:
                transformation[1] = new CropCircleTransformation(config.getContext());
                break;

            case ShapeMode.SQUARE:
                transformation[1] = new CropSquareTransformation(config.getContext());
                break;
        }

        if (transformation[0] != null && transformation[1] != null && transformation[2] != null) {
            request.bitmapTransform(transformation);
        } else if (transformation[0] != null && transformation[1] == null) {
            request.bitmapTransform(transformation[0]);
        } else if (transformation[0] == null && transformation[1] != null) {
            request.bitmapTransform(transformation[1]);
        }else if(transformation[0] == null && transformation[1] == null && transformation[2] != null){
            request.bitmapTransform(transformation[2]);
        }
    }

    @Override
    public void pause() {
        Glide.with(GlobalConfig.context).pauseRequestsRecursive();

    }

    @Override
    public void resume() {
        Glide.with(GlobalConfig.context).resumeRequestsRecursive();
    }

    @Override
    public void clearDiskCache() {
        Glide.get(GlobalConfig.context).clearDiskCache();
    }

    @Override
    public void clearMomoryCache(View view) {
        Glide.clear(view);
    }

    @Override
    public void clearMomory() {
        Glide.get(GlobalConfig.context).clearMemory();
    }

    @Override
    public File getFileFromDiskCache(String url) {
        return null;
    }

    @Override
    public boolean isCached(String url) {
        return false;
    }

    @Override
    public void trimMemory(int level) {
        Glide.with(GlobalConfig.context).onTrimMemory(level);
    }

    @Override
    public void clearAllMemoryCaches() {
        Glide.with(GlobalConfig.context).onLowMemory();
    }
}

看一下效果哦: 这里写图片描述

到这里我们的封装就结束了,就可以愉快的使用了,欢迎大家提出意见与建议。

Glide二次封装库源码

后面会更新到jcenter,并会出一篇具体如何使用本库的文章,还请大家持续关注哦。