天天看点

Glide使用简要说明

直接用代码方式说下:

Glide.with(act).load(strImage)
                    /**
                     * Glide加载时我们可以通过fitCenter()和
                     * centerCrop方法直接在代码中对ImageView进行设置
                     * fitCenter() 是裁剪技术,即缩放图像让图像都测量
                     * 出来等于或小于 ImageView 的边界范围。该图像
                     * 将会完全显示,但可能不会填满整个 ImageView
                     * CenterCrop()是一个裁剪技术,即缩放图像让它填
                     * 充到 ImageView 界限内并且裁剪额外的部
                     * 分。ImageView 可能会完全填充,但图像可能不会
                     * 完整显示。
                     */
                    .centerCrop()
                    /**
                     * Glide有淡入淡出的效果,因为它有
                     crossFade()
                     crossFade(intanimationId, int duration)
                     crossfade(intduration)动画默认的持续
                     时间是 300毫秒
                     */
                    .crossFade()
                    /**
                     * 加载小图,圆图的1/8
                     */
                    .thumbnail( /)
                    /**
                     * DiskCacheStrategy.NONE(不做任何磁盘缓存)
                     DiskCacheStrategy.RESULT(缓存转换后的资源)
                     DiskCacheStrategy.SOURCE(缓存源资源)
                     */
                    .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                     /**
                     * 如果图片不会自动适配到 ImageView,调用 
                     * override(horizontalSize, verticalSize) 
                     * 这将在图片显示到 ImageView之前重新改变图片大小
                     */
                    .override(, ) 
                    //占位图
                    .placeholder(R.mipmap.ic_headimg)
                    //加载错误时显示的图片
                    .error(R.mipmap.ic_headimg)
                    /**
                     * 如果你想直接显示图片而没有任何淡入淡出效果,
                     * 在 Glide 的建造者中调用 .dontAnimate()
                     */
                    .dontAnimate()
                    .into(my_avatar_img);
           

另外Glide还有gif检查功能:Gif 检查

一个潜在的问题是,如果提供的来源不是一个 Gif,可能只是一个常规图片,这就没有办法显示这个问题。Glide 接受 Gif 或者图片作为 load() 参数。如果你期望这个 URL 是一个 Gif,Glide 不会自动检查是否是 Gif。因此他们引入了一个额外的防区强制 Glide变成一个 Gif asGif():
Glide  
    .with( context )
    .load( gifUrl )
    .placeholder( R.drawable.cupcake )
    .error( R.drawable.full_cake )
    .into( imageViewGif );
    这样做的的好处是,.error() 回调被调用并且错误占位符被显示,即使 gifUrl 是一个完美的图片(但不是一个 Gif)。
           

Gif 转为 Bitmap

如果你的 App 显示一个位置的网络 URL 列表,它可能遇到常规的图片或者 Gif。在某些情况下,你可能对不想系那是整个 Gif。如果你仅仅想要显示 Gif 的第一帧,你可以调用 asBitmap() 去保证其作为一个常规的图片显示,即使这个 URL 是一个 Gif。

Glide  
    .with( context )
    .load( gifUrl )
    .asBitmap()
    .into( imageViewGifAsBitmap );
           

显示本地视频

现在来谈谈视频。Glide 还能显示视频!只要他们是存储在手机上的。让我们假设你通过让用户选择一个视频后得到了一个文件路径:

String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
Glide  
    .with( context )
    .load( Uri.fromFile( new File( filePath ) ) )
    .into( imageViewGifAsBitmap );
           

这里需要注意的是,这仅仅对于本地视频起作用。如果没有存储在该设备上的视频(如一个网络 URL 的视频),它是不工作的!

使用缓存策略

Glide 提供了方法去适配内存和磁盘缓存行为。让我们先看看内存缓存。

内存缓存

Glide  
    .with( context )
    .load( eatFoodyImages[] )
    .skipMemoryCache( true )
    .into( imageViewInternet );
           

我们调用了 .skipMemoryCache(true) 去明确告诉 Glide 跳过内存缓存。这意味着 Glide 将不会把这张图片放到内存缓存中去。这里需要明白的是,这只是会影响内存缓存!Glide 将会仍然利用磁盘缓存来避免重复的网络请求。这也容易知道 Glide 将会默认将所有的图片资源放到内存缓存中去。因为,指明调用 .skipMemoryCache(false) 是没有必要的。

提示:注意一个事实,对于相同的 URL ,如果你的初始请求没调用 .skipMemoryCache(true) 方法,你后来又调用了 .skipMemoryCache(true) 这个方法,这个资源将会在内存中获取缓存。当你想要去调整缓存行为时,确保对同一个资源调用的一致性。

跳过磁盘缓存

你可以用 .diskCacheStrategy() 方法为 Glide 改变磁盘缓存的行为。不同的于 .skipMemoryCache() 方法,它需要一个枚举而不是一个简答的布尔值。如果你想要为一个请求禁用磁盘缓存。使用枚举 DiskCacheStrategy.NONE 作为参数。

Glide  
    .with( context )
    .load( eatFoodyImages[] )
    .diskCacheStrategy( DiskCacheStrategy.NONE )
    .into( imageViewInternet );
图片在这段代码片段中将不会被保存在磁盘缓存中。然而,默认的它将仍然使用内存缓存!为了把这里两者都禁用掉,两个方法一起调用:

Glide  
    .with( context )
    .load( eatFoodyImages[] )
    .diskCacheStrategy( DiskCacheStrategy.NONE )
    .skipMemoryCache( true )
    .into( imageViewInternet );
           

自定义磁盘缓存行为

对于 .diskCacheStrategy() 方法来说不同的枚举参数的意义:

DiskCacheStrategy.NONE 什么都不缓存,就像刚讨论的那样
DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像。在我们上面的例子中,将会只有一个 x1000 像素的图片
DiskCacheStrategy.RESULT 仅仅缓存最终的图像,即,降低分辨率后的(或者是转换后的)
DiskCacheStrategy.ALL 缓存所有版本的图像(默认行为)
作为最后一个例子,如果你有一张图片,你知道你将会经常操作处理,并做了一堆不同的版本,对其有意义的仅仅是缓存原始分辨率图片。因此,我们用 DiskCacheStrategy.SOURCE 去告诉 Glide 仅仅保存原始图片:

Glide  
    .with( context )
    .load( eatFoodyImages[] )
    .diskCacheStrategy( DiskCacheStrategy.SOURCE )
    .into( imageViewFile );
           

图片请求的优先级

了解 Priority (优先级)枚举

这个枚举给了四个不同的选项,下面是按照递增priority(优先级)的列表:

Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE
在我们开始例子前,你应该知道的是:优先级并不是完全严格遵守的。Glide 将会用他们作为一个准则,并尽可能的处理这些请求,但是它不能保证所有的图片都会按照所要求的顺序加载。

然而,如果你有的使用场景是确定一些图片是重要的,充分利用它!
           
让我们开始回到开始时的例子吧。你正在实现一个信息详情页面,有一个英雄图片在顶部,和较小的图片在底部。对于最好的用户体验来说,英雄图片首先需要被加载。因此,我们用 Priority.HIGH 来处理它。理论上说,这应该够了,但是为了让这个实例增加点趣味,我们也将底层图像分配给低优先级,用 .priority(Priority.LOW) 调用:

private void loadImageWithHighPriority() {  
    Glide
        .with( context )
        .load( UsageExampleListViewAdapter.eatFoodyImages[] )
        .priority( Priority.HIGH )
        .into( imageViewHero );
}

private void loadImagesWithLowPriority() {  
    Glide
        .with( context )
        .load( UsageExampleListViewAdapter.eatFoodyImages[] )
        .priority( Priority.LOW )
        .into( imageViewLowPrioLeft );

    Glide
        .with( context )
        .load( UsageExampleListViewAdapter.eatFoodyImages[] )
        .priority( Priority.LOW )
        .into( imageViewLowPrioRight );
}
如果你运行这个实例,你会看到,在几乎所有的情况下,英雄图片将会首先显示出来。尽管是更大的图像(因为需要更多的处理时间)。
           

简单的缩略图

Glide 的 .thumbnail() 方法让这一切成为可能。 在这样的情况下,这个参数是一个 float 作为其大小的倍数。

Glide  
    .with( context )
    .load( UsageExampleGifAndVideos.gifUrl )
    .thumbnail( f )
    .into( imageView2 );
例如, 你传了一个 f 作为参数,Glide 将会显示原始图像的%的大小。如果原始图像有 x1000 像素,那么缩略图将会有 x100 像素。因为这个图像将会明显比 ImageView 小很多,你需要确保它的 ScaleType 的设置是正确的。
           

Glide 中的回调:Targets

我们假定 ImageView 不再是图像的最后一步。我们只要 Bitmap 本身。Glide 提供了一个用 Targets 的简单的方式去接受图片资源的 Bitmap。Targets 是没有任何别的回调,它在 Glide 做完所有的加载和处理之后返回结果。Glide 提供了各种的 targets 并且每个都有其明确的目的。我们将在接下来的几节中通过使用它们。让我们从 SimpleTarget 开始。

SimpleTarget

private SimpleTarget target = new SimpleTarget<Bitmap>() {  
    @Override
    public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
        // do something with the bitmap
        // for demonstration purposes, let's just set it to an ImageView
        imageView1.setImageBitmap( bitmap );
    }
};

private void loadImageSimpleTarget() {  
    Glide
        .with( context ) // could be an issue!
        .load( eatFoodyImages[] )
        .asBitmap()
        .into( target );
}
           

这段代码的第一部分创建了一个字段对象,声明了一个方法,即一旦 Glide 已加载并处理完图像,它将被调用。这个回调方法传了 Bitmap 作为一个参数。你之后便可以使用这个 Bitmap 对象,无论你要怎样用它。这段代码的第二部分是我们如何通过 Glide 用 targets:和 ImageView 用法完全相同的!你既可以传一个 Target 也可以传一个 ImageView 参数给 .into() 方法。Glide 自己将会处理并返回结果给任何一个。这里有一些不同的是,我们添加了 .asBitmap(),它强制 Glide 去返回一个 Bitmap 对象。记住,Glide 也可以加载 Gif 或 video 的。为了防止 target 的冲突(我们需要 Bitmap) 和未知资源在网络背后的 URL(可能是一个 Gif),我们可以调用 .asBitmap() 告诉 Glide 我们需要一个图像。

除了知道如何实现一个简单版本的 Glide 的 Target 回调系统,你要学会额外两件事。

首先是 SimpleTarget 对象的字段声明。从技术上来说,Java/Android 会允许你在 .into() 方法中去声明 target 的匿名内部类。然而,这大大增加了这样一个可能性:即在 Glide 做完图片请求之前, Android 垃圾回收移除了这个匿名内部类对象。最终这可能会导致一个情况,当图像加载完成了,但是回调再也不会被调用。所请确保你所声明的回调对象是作为一个字段对象的,这样你就可以保护它避免被邪恶的 Android 垃圾回收机制回收 ;-)

第二个关键部分是 Glide 建造者中这行:.with(context)。 这里的问题实际是 Glide 的功能:当你传了一个 context,例如是当前应用的 activity,Glide 将会自动停止请求当请求的 activity 已经停止的时候。这整合到了应用的生命周期中通常是非常有帮助的,但是有时工作起来是困难的,如果你的 target 是独立于应用的 activity 生命周期。这里的解决方案是用 application 的 context: .with(context.getApplicationContext))。当应用资深完全停止时,Glide 才会杀死这个图片请求。请求记住,再说一次,如果你的请求需要在 activity 生命周期之外去做时,才用下面这样的代码:

private void loadImageSimpleTargetApplicationContext() {  
    Glide
        .with( context.getApplicationContext() ) // safer!
        .load( eatFoodyImages[] 
        .asBitmap()
        .into( target2 );
}
           

Target 指定尺寸

另一个潜在的问题是,target 没有指明大小。如果你你传一个 ImageView 作为参数给 .into(),Glide 将会用 ImageView 的大小去限制图像的大小。比如说,如果加载的图片是 x1000 像素的,但是 ImageView 只有 x250 像素,Glide 将会减少图片的尺寸去节省时间和内存。很显然,在和 target 协作的时候并没有这么做,因为我们并没有已知的大小。然而,如果你有一个指定的大小,你可以提高回调。如果你知道这种图片应该要多大,你应该在你的回调声明中指定它以节省一些内存。

private SimpleTarget target2 = new SimpleTarget<Bitmap>( ,  ) {  
    @Override
    public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
        imageView2.setImageBitmap( bitmap );
    }
};

private void loadImageSimpleTargetApplicationContext() {  
    Glide
        .with( context.getApplicationContext() ) // safer!
        .load( eatFoodyImages[] )
        .asBitmap()
        .into( target2 );
}
           

还有很多方法以后再学习…