Glide v4

Photo by Jakob Owens on Unsplash

学习于:https://bumptech.github.io/glide/
http://blog.csdn.net/u013005791/article/details/74532091

  • GlideV4中如centerCrop()placeholder()等方法已经不能直接通过流式API的方式调用;
    如果还是想通过V3版本的方式调用,官方也提供了一种解决方案:

  • 添加依赖

repositories {
  mavenCentral()
}

dependencies {
    compile 'com.github.bumptech.glide:glide:4.0.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0'
    compile 'com.android.support:support-v4:25.3.1'
}

并且创建一个AppGlideModule的实现类,之后Rebuild工程,然后就能找到GlideApp对象了,然后就可以和Glide v3一样使用了;

AppGlideModule如果注释不存在,则不会发现该模块,并且您将在日志中看到一条带有Glide日志标记的警告,该日志标记指示该模块无法找到。


接下来将在V4基础上重新学习Glide的用法;

  • RequestOptions
    Glide中的大多数设置都可以使用RequestOptions类和apply()方法来应用;
        /**
         * 磁盘缓存策略:diskCacheStrategy(DiskCacheStrategy.NONE)
         *
         * DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
         * DiskCacheStrategy.NONE 不使用磁盘缓存
         * DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
         * DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
         * DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
         */

        /**
         * 优先级:priority(Priority.HIGH)
         * 
         * Priority.LOW 
         * Priority.NORMAL 
         * Priority.HIGH 
         * Priority.IMMEDIATE
         */

        RequestOptions options = new RequestOptions()
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .fallback(R.mipmap.ic_launcher)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .priority(Priority.HIGH)
                .override(800,800)
                .circleCrop();
//                .transform(new GlideRoundTransform (context))
//                .centerInside();
//                .centerCrop();


        Glide.with(this)
                .load(R.mipmap.gifpic)
                .apply(options)
                .into(imageView);

**清除缓存**:
//清理磁盘缓存 需要在子线程中执行
 Glide.get(this).clearDiskCache();
//清理内存缓存 可以在UI主线程中进行
 Glide.get(this).clearMemory();

apply:应用ResquestOptions对象,该方法可以调用多次,但是如果两次apply存在冲突的设置,会以最后一次为准;

placeholder(占位符):当请求成功完成时,占位符将被替换为请求的资源。如果从内存中加载所请求的资源,则占位符可能永远不会显示。如果请求失败,并且未设置error(),占位符将继续显示。类似地,如果所请求的url / model是null并且既不设置error()也不是fallback(),则占位符也将继续显示;
占位符是从Android资源在主线程上加载的,所以尽可能是小的容易缓存的资源;
error:当请求永久失败时显示。如果所请求的url / model是null并且没有设置fallback(),则也显示;
fallback:当请求的url / model是null的时候,显示fallback()设置的资源;

CenterCrop:缩放宽和高都到达View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能超过边界;
CenterInside :如果宽和高都在View的边界内,那就不缩放,否则缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
CircleCrop :圆形且结合了CenterCrop的特性;
FitCenter:缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
但是其实完全可以在layout文件中设置ImageView为android:scaleType="centerCrop",Glide会自动根据这个属性设置图片的显示方式;

overrid:Glide 会根据ImageView的大小,自动限制图片缓存和内存中的大小,同时也可以调用override(width, height)限制图片的大小;

transform:自定义GlideRoundTransform类实现圆角图片;

/**
 * Created by whstywh on 2017/4/5
 * GitHub:https://github.com/whstywh
 * email:whstywh@gmail.com
 * description:自定义Glide圆角图片类
 */

public class GlideRoundTransform extends BitmapTransformation {

    public GlideRoundTransform(Context context) {
        super(context);
    }

    /**
     * 重写 生成圆角图片
     *
     * @param pool
     * @param toTransform
     * @param outWidth
     * @param outHeight
     * @return
     */
    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        //画布中背景图片与绘制图片交集部分
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {
    }
}

  • TransitionOptions
    有三种:
    GenericTransitionOptions
    DrawableTransitionOptions
    BitmapTransitionOptions

为避免突然变化,您可以在图像切换时设置淡入淡出;

       Glide.with(this)
               .load(R.mipmap.gifpic)
               .apply(options)
               .transition(DrawableTransitionOptions.withCrossFade())
//                .transition(BitmapTransitionOptions.withCrossFade())
//                .transition(GenericTransitionOptions.with())
               .into(imageView);

TransitionOptions并且与Glide要加载的资源类型相关;
因此,如果你要求Drawable,则需要使用交叉淡入浅出DrawableTransitionOptions.withCrossFade(),如果您要求Bitmap,则需要使用简单的淡入淡出BitmapTransitionOptions.withCrossFade();如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions

如果要使用自定义的动画,可以使用GenericTransitionOptions.with(int viewAnimationId)或者BitmapTransitionOptions.withCrossFade(int animationId, int duration)或者DrawableTransitionOptions.withCrossFade(int animationId, int duration)

出于性能考虑,最好不要在ListView,GridView,RecycleView中使用过渡动画,可以使用.dontAnimate()不加载动画:

        RequestOptions options = new RequestOptions()
                ...
                .dontAnimate()
  • RequestBuilder
        RequestBuilder<Drawable> requestBuilder = Glide.with(this)
                .asGif()
//                .asBitmap()
//                .asDrawable()
//                .asFile()
                .load(R.mipmap.gifpic);

        requestBuilder.thumbnail(0.1f)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        Log.d("flag", "onLoadFailed");
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        Log.d("flag", "onResourceReady");
                        return false;
                    }
                })
                .apply(options)
                .transition()
                .into(imageView);

with:方法相比Picasso而言不仅接受Context,还接受Activity,Fragment,View;


加载GIF
如果使用了.asGif()方法,图片会强制转换成gif图,此时传入的图片就必须是gif图,否则会报错。当然不使用.asGif()方法同样也可以加载gif图;
load:方法中可以传入联网请求的url,资源id,File;相比Picasso还支持GIF图,本地MP4播放;

thumbnail:设置缩略图,传入一个(0,1)之间的float数值时,表示缩略图为原图的十分之几,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示;如果缩略图也来自网络获取时,代码如下:

        requestBuilder.thumbnail(Glide.with(this).load(thumbnailUrl))
                 ...
                .into(imageView);

listener:监听资源加载的请求状态,可以使用两个回调:onResourceReadyonLoadFailed,但不要每次请求都使用新的监听器,要避免不必要的内存申请,可以使用单例进行统一的异常监听和处理。
apply:应用RequestOptions
transition:应用TransitionOption


Recycle的加载优化
只在拖动和静止时加载,自动滑动时不加载。

        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        Glide.with(MainActivity.this).resumeRequests();//加载
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING:
                        Glide.with(MainActivity.this).pauseRequests();//暂停加载
                        break;
                    case RecyclerView.SCROLL_STATE_IDLE:
                        Glide.with(MainActivity.this).resumeRequests();//加载
                        break;
                }
            }
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });

  • Glide和Picasso的区别

Glide默认的Bitmap格式是RGB_565 ,比 Picasso的ARGB_8888格式的内存开销要小一半。

Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。而Glide加载的大小和ImageView的大小是一致的,因此内存花销更小。

Picasso和Glide在磁盘缓存策略上有很大的不同。Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。

尝试将ImageView调整成不同大小,但不管大小如何Picasso只缓存一个全尺寸的。Glide则不同,它会为每种大小的ImageView缓存一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,则需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。

另外Glide也可以既缓存全尺寸又缓存其他尺寸:

Glide.with(this)  
     .load(url)  
     .diskCacheStrategy(DiskCacheStrategy.ALL)  
     .into(imageView); 

Glide的优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致有一些延迟。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 效果图: 点此进入目录:[干货] 十天 教你从创意到上线APP 在图片加载库繁荣昌盛的今天,选择一个适合自己使用的...
    常思行阅读 2,486评论 0 4
  • 写在前面 Android 中有几个比较有名的图片加载框架,Universal ImageLoader、Picass...
    依然范特稀西阅读 37,088评论 33 121
  • Glide 是一个 android 平台上的快速和高效的开源的多媒体资源管理库,提供 多媒体文件的压缩,内存和磁盘...
    帅气的欧巴阅读 2,762评论 1 18
  • 目前市场上的图片异步请求框架有很多,比如Volley,Fresco,Glide,Picasso等,之前项目中用的一...
    junjunxx阅读 1,121评论 1 8
  • 1、基本使用 添加Glide到你的设置中首先,添加Glide到你的工程依赖里,截止本文写作时,最新的Glide版本...
    南城的人阅读 746评论 0 2