1.引入工程
Android Studio中引入工程,只需要在gradle
中配置一下代码
dependencies {
compile 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
}
2.配置基础项
Glide中需要在AppGlideModule
的实现中完成基础项的配置,配置内容有内存大小
,磁盘缓存路径大小
,还有各种解码方式
等。配置方式为:
1.实现AppGlideModule,applyOptions
方法中配置基础信息,registerComponents
方法中添加解码相关的信息。
2.如果没有annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
,则需要在AndroidManifest
文件中配置一下代码
如果有则,通过注解实现,在实现类上添加@GlideModule注解
@GlideModule
public class MyGlideMoudle extends AppGlideModule {}
3.基本用法
基本使用
多数情况下,使用Glide加载图片非常简单,一行代码足矣:
Glide.with(fragment)
.load(myUrl)
.into(imageView);
取消加载同样很简单:
Glide.with(fragment).clear(imageView);
在 ListView 或 RecyclerView 中加载图片的代码和在单独的 View 中加载完全一样。Glide 已经自动处理了 View 的复用和请求的取消:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String url = urls.get(position);
Glide.with(fragment)
.load(url)
.into(holder.imageView);
}
Glide 唯一的要求是,对于任何可复用的 View
或 Target
,如果它们在之前的位置上,用 Glide 进行过加载操作,那么在新的位置上要去执行一个新的加载
操作,或调用 clear()
API 停止 Glide 的工作。如果没有,那么可能会导致错乱问题。
Target
Into对象不一定是View也可能是target,默认是Target
Target target = Glide.with(this).asBitmap()
.load(url)
.into(new Target() {
})
into方法返回一个Target
对象,可通过该对象进行取消
和重用
。
1.重新请求
Glide.with(this).asBitmap().load(newUrl).into(target);
2.清除请求
Glide.with(this).clear(target);
into(ImageView)是最常用的方式,ImageView最终会封装成ImageViewTarget
实例,因为ImageView使用了getTag
和setTag
方法来存储每个请求的相关信息,所以我们可以直接通过ImageView复用
和清除
。
1.重新请求
Glide.with(this).load(newUrl).into(img);
2.清除请求
Glide.with(this).clear(img);
Glide ViewTarget 尺寸设置
ViewTarget 通过检查 View 的属性和/或使用一个 OnPreDrawListener 在 View 绘制之前直接测量尺寸来实现 getSize() 方法。因此, Glide 可以自动调整大部分图片以匹配目标 View。加载更小的图片可使 Glide 更快地完成加载 (在缓存到磁盘以后), 并使用更少的内存,在图片尺寸一致时还可以增加 Glide 的 BitmapPool 的命中率。其内部逻辑为:
1.如果 View 的布局参数尺寸 > 0 且 > padding,则使用该布局参数;
2.如果 View 尺寸 > 0 且 > padding,使用该实际尺寸;
3.如果 View 布局参数为 wrap_content 且至少已发生一次 layout ,则打印一行警告日志,建议使用 Target.SIZE_ORIGINAL 或通过 override() 指定其他固定尺寸,并使用屏幕尺寸为该请求尺寸;
4.其他情况下(布局参数为 match_parent, 0, 或 wrap_content 且没有发生过 layout ),则等待布局完成,然后回溯到步骤1。
我们可以通过RequestOption.override
(400,400)方法。或者定制Target重写getSize
方法修改尺寸:
@Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
}
SIZE_ORIGINAL
非常低效,如果图片够大容易导致OOM
,所以我们需要在创建是传入固定宽高。
如下所示:
public class CustomTarget implements Target {
private final int width;
private final int height;
public CustomTarget(int width, int height) {
this.width = width;
this.height = height;
}
...
@Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(width, height);
}
}
如果不知道所需的具体尺寸,但可以异步地得出结果,也可以使用列表持有在getSize()
中给出的任何回调,然后执行异步过程并稍后在得出尺寸之后通知持有的这些回调。如果持有了这些回调,请确保同时实现 removeCallback
以避免内存泄露。如果需要一个示例,请参考 ViewTarget
中的逻辑。
在使用 RecyclerView
时,View 可能被重用且保持了前一个位置的尺寸,但在当前位置会发生改变。
为了处理这种场景,你可以创建一个新的 ViewTarget 并为 waitForLayout()
方法传入true
:
public void onBindViewHolder(VH holder, int position) {
Glide.with(fragment)
.load(urls.get(position))
.into(new DrawableImageViewTarget(holder.imageView, /**waitForLayout=*/true))
}
加载gif资源
Glide默认支持gif资源加载,使用方式和普通资源一样。如果需要手动控制gif资源,可以这么做:
Glide.with(this).asGif().load(gifUrl).into(new CustomTarget() {
@Override
public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition super GifDrawable> transition) {
img.setImageDrawable(resource);
resource.start();
}
});
如果不能确定是gif资源可以通过一下代码来判定是否是gif:
if (resource instanceof Animatable){
((Animatable) resource).start();
}
Glide 占位符系列
placeholder
加载过程中占位符
error
error Drawable 在请求永久性失败时展示 error Drawable 同样也在请求的url/model为 null ,且并没有设置 fallback Drawable 时展示。
Fallback
fallback Drawable 在请求的url/model为 null 时展示
Glide 选项设置
RequestBuilder
是Glide中请求的骨架,负责携带请求的url和你的设置项来开始一个新的加载过程。
Glide中的大部分设置项都可以直接应用RequestBuilder对象上,比如但不仅仅:
1.占位符(Placeholders)
2.转换(Transformations)
3.缓存策略(Caching Strategies)
4.组件特有的设置项,例如编码质量,或Bitmap的解码配置等()
使用 RequestBuilder 可以指定:
你想加载的资源类型(Bitmap, Drawable, 或其他)
你要加载的资源地址(url/model)
你想最终加载到的View
任何你想应用的(一个或多个)RequestOption 对象
任何你想应用的(一个或多个)TransitionOption 对象
任何你想加载的缩略图 thumbnail()
通过Glide.with(this)
选定类型或者load
一个资源会获得RequestBuilder:
RequestBuilder bitmapRequestBuilder = requestManager.asBitmap();
或者
RequestBuilder drawableRequestBuilder = requestManager.load("");
选择资源类型
RequestBuilders
是特定于它们将要加载的资源类型的。默认情况下你会得到一个Drawable RequestBuilder
,但你可以使用as...
系列方法来改变请求类型。例如,如果你调用了 asBitmap() ,
你就将获得一个 BitmapRequestBuilder
对象,而不是默认的Drawable RequestBuilder
。
RequestBuilder requestBuilder = Glide.with(fragment).asBitmap();
定制请求 公共配置选项 apply RequestOptions
RequestOptions shareOptions = new RequestOptions().placeholder(placeHolderId).circleCrop();
Glide.with(this)
.load(url)
.apply(shareOptions)
.into(img);
过度选项TransitionOptions
TransitionOptions
用于决定你的加载完成时会发生什么。现象是加载资源View淡入淡出
,与占位符交叉替换
或者什么都不发生
图像将会“跳入”其显示位置,直接替换掉之前的图像。一般情况下为了图像能够顺滑过度我们都会采用一些效果。
Glide.with(this).asBitmap()
.load(url)
.transition(BitmapTransitionOptions.withCrossFade(3000)).into(img);
不同于RequestOptions,TransitionOptions是特定资源类型独有
的,你能使用的变换取决于你让Glide加载哪种类型的资源。Bitmap
类型的请求使用BitmapTransitionOptions
,而不是DrawableTransitionOptions
缩略图 (Thumbnail) 请求
Glide 的 thumbnail() API 允许你指定一个 RequestBuilder
与你的主请求并行启动
。thumbnail
() 会在主请求加载过程中展示。如果主请求在缩略图请求之前
完成,则缩略图请求中的图像将不会被展示
。thumbnail()
API 允许你简单快速地加载图像的低分辨率版本,并且同时加载图像的无损版本,这可以减少用户盯着加载指示器 【例如进度条】 的时间。thumbnail()
API 对本地和远程图片都适用,尤其是当低分辨率缩略图存在于 Glide 的磁盘缓存时,它们将很快被加载出来。
加载不同的线上缩略图
Glide.with(this).load(url)
.thumbnail(Glide.with(this).load(thumbnailUrl))
.into(img);
加载本地缩略图
Glide.with(this).load(Url)
.thumbnail(Glide.with(this).load(localUrl).override(3)).into(img);
加载原图缩略图
Glide.with(this).load(url)
.thumbnail(0.25f).into(img);
在失败时开始新的请求
Glide.with(this).load(url).error(Glide.with(this).load(errorUrl)).into(img);
如果主请求成功完成,这个error RequestBuilder
将不会被启动。如果你同时指定了一个 thumbnail()
和一个 error() RequestBuilder
,则这个后备的 RequestBuilder
将在主请求失败时启动,即使缩略图请求成功也是如此。
组件选项
Option 类是给Glide的组件添加参数的通用办法,包括 ModelLoaders
, ResourceDecoders
, ResourceEncoders
, Encoders
等等。一些Glide的内置组件提供了设置项,自定义的组件也可以添加设置项。
Glide.with(context)
.load(url)
.option(MyCustomModelLoader.TIMEOUT_MS, 1000L)
.into(imageView);
或者通过设置RequestOptions
,然后应用RequestOptions
。
RequestOptions options = new RequestOptions()
.set(MyCustomModelLoader.TIMEOUT_MS, 1000L);
Glide.with(context)
.load(url)
.apply(options)
.into(imageView);
Glide 变换策略
在Glide中,Transformations
可以获取资源并修改它,然后返回被修改后的资源。通常变换操作是用来完成剪裁或对位图应用过滤器,但它也可以用于转换GIF动画,甚至自定义的资源类型。
Glide 提供了很多内置的变换,包括:
CenterCrop
FitCenter
CircleCrop
默认使用方法
Glide.with(this)
.load(url)
.circleCrop().into(img);
或者使用RequestOptions
RequestOptions options = new RequestOptions().circleCrop();
Glide.with(this)
.load(url)
.apply(options)
.into(img);
多重变换
1.Glide.with(this)
.load(url)
.transform(new FitCenter(),new RoundedCorners(20)).into(img);
或者
Glide.with(this)
.load(url)
.transform(new MultiTransformation<>(new FitCenter(),new RoundedCorners(20))).into(img);
自定义变换
尽管 Glide 提供了各种各样的内置 Transformation
实现,如果你需要额外的功能,你也可以实现你自己的 Transformation。通常情况下我们针对Bitmap做处理的话,只需要继承BitmapTransformation
就行,其内部帮助我们处理了基础的操作。
下面我们来进行处理
Glide.with(this)
.load(url)
.transform(new CustomBitmapTransformation(2400,1500)).into(img);
CustomBitmapTransformation
是自定义的变换方式,继承BitmapTransformation 实现hashcode
equal ``updateDiskCacheKey
和transform
方法。其中transform
是变换的核心用来处理图片效果。ImageView的默认依据scaleType
进行变换,如果 scaleType
是 CENTER_CROP
,Glide
将会自动应用 CenterCrop
变换。如果scaleType
为FIT_CENTER
或 CENTER_INSIDE
,Glide
会自动使用 FitCenter
变换。
Glide 过渡 策略
Glide 提供了很多的过渡效果,用户可以手动地应用于每个请求。Glide 的内置过渡以一致的方式运行,并且将根据加载图像的位置在某些情况下避免运行。
在 Glide 中,图像可能从四个地方中的任何一个位置加载出来:
Glide 的内存缓存
Glide 的磁盘缓存
设备本地可用的一个源文件或 Uri
仅远程可用的一个源 Url 或 Uri
如果图像从 Glide 的内存缓存中加载出来,Glide 的内置过渡将不会执行。然而,在另外三种场景下,Glide 的内置过渡都会被执行。
注意在列表中最好禁用过度
,否则容易引起性能问题。
TransitionOptions通过transition来应用,之前有过说明,所以我们主要关注下自定义TransitionOptions的实现
官方文档中给出,如果要定义一个自定义的过渡动画,你需要完成以下两个步骤:
1、实现 TransitionFactory . 然后
2、使用 DrawableTransitionOptions#with 来将你自定义的 TransitionFactory 应用到加载中。
注意如果要改变你的 transition
的默认行为,以更好地控制它在不同的加载源(内存缓存,磁盘缓存,或uri)下是否被应用,你可以检查一下你的 TransitionFactory
中传递给 build()
方法的那个 DataSource
。下面我们参考一下 DrawableCrossFadeFactory
实现过度动画:
Glide.with(this)
.load(url)
.transition(DrawableTransitionOptions.with(new CustomTransitionFactory(true,3000))).into(img);
Glide 缓存 策略
AppMoudle中配置了缓存策略,可在使用中开启和关闭
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(img);
通过设置onlyRetrieveFromCache(true)
,设置仅仅从缓存中获取
通过skipMemoryCache(true)
跳过内存缓存
通过diskCacheStrategy(DiskCacheStrategy.NONE)
跳过磁盘缓存
参考文档:
Glide官方文档