您的位置:首页 > 其它

Glide最新版V4使用指南

2018-01-12 17:26 274 查看
概述

集成
基本用法
注解V4新特性和自定义方法
1 在项目中实现AppGlideModule
2 GlideExtension
21 GlideOption
22 GlideType

占位符
设置占位符

Options
1 RequestOptions
2 TransitionOptions
3 RequestBuilder

Transformations
使用RequestOptions
使用RequestOptions中的transform方法
V4特性
多个变换

Transitions动画
普通动画
自定义过渡动画

基本配置
1 配置内存缓存
方法一
方法二
方法三

2 磁盘缓存
3 禁止解析Manifest文件
4 View尺寸
方法一 继承ImageViewTarget
方法二 使用override


概述

Glide是一个Android的图片加载和缓存库,它主要专注于大量图片的流畅加载,Glide几乎可以胜任任何你需要使用到图片从网络拉取,压缩,显示的场景。

本文主要基于Glide4.0版本介绍其基本使用方法。


1 集成

Github地址: https://github.com/bumptech/glide

app或lib级别的
build.gradle
文件添加依赖:
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}

dependencies {
compile 'com.github.bumptech.glide:glide:4.3.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
}
1
2
3
4
5
6
7
8
9

Android Studio3.0使用:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.3.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
}
1
2
3
4

proguard.pro
/
proguard.cfg
中添加混淆:
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.mo
1aa70
dule.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
1
2
3
4
5
6
7
8
9


2 基本用法

大多数情况下加载图片只需要一行代码:
Glide.with(fragment)
.load(myUrl)
.into(imageView);
1
2
3

取消加载也很简单:
Glide.with(fragment).clear(imageView);
1

实际上你并不需要取消加载。。。

因为当你在
with
方法中传入的
Activity
Fragment
被销毁的时候,Glide会自动取消加载并且回收所有的加载过程中所使用的资源。


3 注解(V4新特性)和自定义方法

Glide使用了
annotation processor
来生成API,允许应用修改
RequestBuilder
RequestOptions
和任意的包含在单一流式API库中的方法。这是V4的特性,运用注解后使用起来更方便:
GlideApp.with(fragment)
.load(myUrl)
.placeholder(R.drawable.placeholder)
.fitCenter()
.into(imageView);
1
2
3
4
5

Glidev4中的
Glide.with().load()
后没有之前版本的
fitCenter
placeholder
这样的方法,但是
GlideApp
有,可以直接在builder中使用。
GlideApp
可以代替之前版本的
Glide
开头。

这样做的目的是:

1.对于library项目来讲可以使用自定义方法继承Glide的API 

2.对于应用来讲,在继承Glide的API后,可以通过添加自定义方法。

虽然你也可以手动继承
RequestOptions
,但是显然这样做更加麻烦,也破坏了流式API特性。


3.1 在项目中实现
AppGlideModule

@GlideModule
public class CustomGlideModule extends AppGlideModule {}
1
2

这个类实现必须要有
@GlideModule
注解,如果你添加的方法失效,那就检查下这里。

如果是library就实现
LibraryGlideModule
,以使用OkHttp为例:
@GlideModule
public final class OkHttpLibraryGlideModule extends LibraryGlideModule {
@Override
public void registerComponents(Context context, Registry registry) {
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
}
}
1
2
3
4
5
6
7

OkHttpUrlLoader是Glide的OKHttp扩展库中的类,如果需要使用Glide的实现,可以在依赖中添加:
compile 'com.github.bumptech.glide:okhttp3-integration:4.3.1'
1

Android Studio 3.0
implementation 'com.github.bumptech.glide:okhttp3-integration:4.3.1'
1

添加完依赖不需要自己实现OkHttpLibraryGlideModule类,库中已经自带了,会自动使用OKHttp的。

然后编译工程可以发现在build中生成了四个类:




3.2 GlideExtension

为了添加新的方法,修改已有的方法或者添加对其他类型格式的支持,你需要在扩展中使用加了注解的静态方法。

GlideOption
用来添加自定义的方法,
GlideType
用来支持新的格式。


3.2.1 GlideOption

先新建一个
CustomGlideExtension
类:
@GlideExtension
public class CustomGlideExtension {
//缩略图的最小尺寸,单位:px
private static final int MINI_THUMB_SIZE = 100;

/**
* 将构造方法设为私有,作为工具类使用
*/
private CustomGlideExtension() {
}

/**
* 1.自己新增的方法的第一个参数必须是RequestOptions options
* 2.方法必须是静态的
* @param options
*/
@GlideOption
public static void miniThumb(RequestOptions options) {
options
.fitCenter()
.override(MINI_THUMB_SIZE);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

编译工程,打开build目录中的
GlideOptions
,可以看见自动生成了两个方法:
public class GlideOptions extends RequestOptions {

/**
* @see CustomGlideExtension#miniThumb(RequestOptions)
*/
public GlideOptions miniThumb() {
CustomGlideExtension.miniThumb(this);
return this;
}

/**
* @see CustomGlideExtension#miniThumb(RequestOptions)
*/
public static GlideOptions miniThumbOf() {
return new GlideOptions().miniThumb();
}

...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

现在可以使用你自定义的方法了:
GlideApp.with(fragment)
.load(url)
.miniThumb(thumbnailSize)
.into(imageView);
1
2
3
4


3.2.2 GlideType

以添加对
GIF
格式的支持为例,只是举例,实际上API中已经支持了。

在刚才的
CustomGlideExtension
类中加上:
@GlideExtension
public class CustomGlideExtension {

private static final RequestOptions DECODE_TYPE_GIF = GlideOptions.decodeTypeOf(GifDrawable.class).lock();

@GlideType(GifDrawable.class)
public static void asGIF(RequestBuilder<GifDrawable> requestBuilder) {
requestBuilder
.transition(new DrawableTransitionOptions())
.apply(DECODE_TYPE_GIF);
}
}
1
2
3
4
5
6
7
8
9
10
11
12

编译工程,打开build目录中的
GlideRequests
,可以看见自动生成了一个方法:
public class GlideRequests extends RequestManager {
/**
* @see CustomGlideExtension#asGIF(RequestBuilder)
*/
public GlideRequest<GifDrawable> asGIF() {
GlideRequest<GifDrawable> requestBuilder = this.as(GifDrawable.class);
CustomGlideExtension.asGIF(requestBuilder);
return requestBuilder;
}
}
1
2
3
4
5
6
7
8
9
10

现在可以使用你添加的类型了:
GlideApp.with(fragment)
.asGIF()
.load(url)
.into(imageView);
1
2
3
4


4 占位符

占位符就是请求的图片没加载出来时显示的默认图片。 

Glide支持三种不同情况下的占位符:
Placeholder 请求图片加载中
Error 请求图片加载错误
Fallback 请求url/model为空


设置占位符:

GlideApp.with(fragment)
.load(url)
.placeholder(R.drawable.placeholder)
.error(new ColorDrawable(Color.RED))
.fallback(new ColorDrawable(Color.GREY))
.into(view);
1
2
3
4
5
6

之后的显示优先级,我画了个流程图。




5 Options


5.1 RequestOptions

Glide中的大多请求参数都可以通过
RequestOptions
类和
apply()
方法来设置。

Glide中的请求参数主要有:
Placeholders 占位符
Transformations 变换
Caching Strategies 缓存策略
组件特定参数:编码质量,解码参数等。

比如,要将图片的显示方式设为
CenterCrop
,你可以这么做:
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;

Glide.with(fragment)
.load(url)
.apply(centerCropTransform(context))
.into(imageView);
1
2
3
4
5
6

但是其实完全可以在layout文件中设置ImageView为
android:scaleType="centerCrop"
,Glide会自动根据这个属性设置图片的显示方式。

apply
方法可以调用多次,但是如果两次
apply
存在冲突的设置,会以最后一次为准。


5.2 TransitionOptions

TransitionOptions
决定图片加载完成如何从占位符图片(或者之前的图片)过渡。
淡入
交叉淡入
不过渡
Glide.with(fragment)
.load(url)
.transition(DrawableTransitionOptions.withCrossFade())
.into(view);
1
2
3
4

注意

TransitionOptions
是和你要加载的资源的类型绑定的,也就是说,如果你请求一张位图(Bitmap),你就需要使用
BitmapTransitionOptions
,而不是
DrawableTransitionOptions
。因此,你请求的这张位图,你需要用简单的淡入,而不能用 

交叉淡入(
DrawableTransitionOptions.withCrossFade()
)。 

如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions


5.3 RequestBuilder

作用:

指定加载类型。
asBitmap()
asGif()
asDrawable()
asFile()

指定要加载url/model。
指定要加载到那个View。
指定要应用的
RequestOption

指定要应用的
TransitionOption

指定要加载的缩略图

那么如何得到
RequestBuilder
呢?
RequestBuilder<Drawable> requestBuilder = Glide.with(fragment);
1

默认得到一个
Drawable RequestBuilder
,如果要指定类型为Bitmap,可以这样写:
RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap();
1

应用
RequestOptions

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment);
requestBuilder.apply(requestOptions);
requestBuilder.transition(transitionOptions);
1
2
3

RequestBuilder
也可以重复使用:
RequestBuilder<Drawable> requestBuilder =
Glide.with(fragment)
.asDrawable()
.apply(requestOptions);

for (int i = 0; i < numViews; i++) {
ImageView view = viewGroup.getChildAt(i);
String url = urls.get(i);
requestBuilder.load(url).into(view);
}
1
2
3
4
5
6
7
8
9
10


6 Transformations

Glide会自动读取ImageView的缩放类型,所以一般在layout文件指定
scaleType
即可。

CenterCrop, CenterInside, CircleCrop, FitCenter, RoundedCorners

Glide支持在java代码中设置这些缩放类型:

CenterCrop 缩放宽和高都到达View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能超过边界
CenterInside 如果宽和高都在View的边界内,那就不缩放,否则缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内
CircleCrop 圆形且结合了CenterCrop的特性
FitCenter 缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内
RoundedCorners 圆角

有三种用法:


1 使用RequestOptions

RequestOptions options = new RequestOptions();
options.centerCrop();

Glide.with(fragment)
.load(url)
.apply(options)
.into(imageView);
1
2
3
4
5
6
7


2 使用RequestOptions中的transform方法

Glide.with(fragment)
.load(url)
.apply(RequestOptions.fitCenterTransform())
.into(imageView);
1
2
3
4


3 V4特性

GlideApp.with(fragment)
.load(url)
.fitCenter()
.into(imageView);
1
2
3
4

第三种方法最简便,推荐。


多个变换

Glide.with(fragment)
.load(url)
.transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
.into(imageView);
1
2
3
4


7 Transitions(动画)


普通动画

Glide中的过渡动画是指占位符到请求图片或缩略图到完整尺寸请求图片的动画。过渡动画只能针对单一请求,不能跨请求执行。

过渡动画执行时机:

1.图片在磁盘缓存 

2.图片在本地 

3.图片在远程

如果图片在内存缓存上是不会执行过渡动画的。如果需要在内存缓存上加载动画,可以这样:
GlideApp.with(this).load(R.drawable.img_default).listener(new RequestListener(){

@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}

@Override
public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
if (dataSource == DataSource.MEMORY_CACHE) {
//当图片位于内存缓存时,glide默认不会加载动画
imageView.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
}
return false;
}
}).fitCenter().transition(GenericTransitionOptions.with(R.anim.fade_in)).into(imageView);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

通常的用法如下:
Glide.with(fragment)
.load(url)
.transition(DrawableTransitionOptions.withCrossFade())
.into(view);
1
2
3
4

TransitionOptions
的介绍:TransitionOptions。有三种TransitionOptions:
GenericTransitionOptions
 通用型
DrawableTransitionOptions

BitmapTransitionOptions


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


出于性能考虑,最好不要在ListView,GridView,RecycleView中使用过渡动画,使用
TransitionOptions.dontTransition()
可以不加载动画,也可以使用
dontAnimate
不加载动画
GlideApp.with(mContext)
.load(imgUrl)
.placeholder(R.drawable.img_default)
.dontAnimate()
.into(holder.imageview);
1
2
3
4
5


自定义过渡动画

1.实现
TransitionFactory
 

2.重写
build()
 

可以控制图片在内存缓存上是否执行动画。

具体写法参考DrawableCrossFadeFactory,然后调用
TransitionOptions
with(TransitionFactory
transitionFactory)
加载。


8 基本配置


8.1 配置内存缓存

Glide会自动合理分配内存缓存,但是也可以自己手动分配。


方法一

通过MemorySizeCalculator设置
@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context)
.setMemoryCacheScreens(2)
.build();
builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
}
}
1
2
3
4
5
6
7
8
9
10

setMemoryCacheScreens
设置MemoryCache应该能够容纳的像素值的设备屏幕数,说白了就是缓存多少屏图片,默认值是2。


方法二

@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int memoryCacheSizeBytes = 1024 * 1024 * 20; // 20mb
builder.setMemoryCache(new LruResourceCache(memoryCacheSizeBytes));
}
}
1
2
3
4
5
6
7
8


方法三

@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setMemoryCache(new CustomGlideMemoryCache());
}
}
1
2
3
4
5
6
7

自己实现
MemoryCache
接口。

清楚内存缓存,在主线程调用:
GlideApp.get(context).clearMemory();
1

在使用的时候,可以跳过内存缓存:
GlideApp.with(getActivity())
.load(url)
.skipMemoryCache(true)
.dontAnimate()
.centerCrop()
.into(imageView);
1
2
3
4
5
6


8.2 磁盘缓存

Glide使用
DiskLruCacheWrapper
作为默认的磁盘缓存,默认大小是250M,缓存文件放在APP的缓存文件夹下。
@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskCacheSizeBytes));
//        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "cacheFolderName", diskCacheSizeBytes));
//        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
}
}
1
2
3
4
5
6
7
8
9
10

用法如上,可以指定缓存在内部存储或外部存储,也可以指定缓存大小和文件夹。

自定义磁盘缓存
@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
return new YourAppCustomDiskCache();
}
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12

自己实现
DiskCache
接口。

清楚磁盘缓存,在主线程调用:
GlideApp.get(context).clearDiskCache();
1

加载图片时设置磁盘缓存策略:
GlideApp.with(getActivity())
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.centerCrop()
.into(imageView);
1
2
3
4
5
6

默认的策略是
DiskCacheStrategy.AUTOMATIC
 

DiskCacheStrategy有五个常量:
DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
DiskCacheStrategy.NONE 不使用磁盘缓存
DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。


8.3 禁止解析Manifest文件

主要针对V3升级到v4的用户,可以提升初始化速度,避免一些潜在错误。
@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
1
2
3
4
5
6
7


8.4 View尺寸

Glide对ImageView的
width
height
属性是这样解析的:

如果
width
height
都大于0,则使用layout中的尺寸。
如果
width
height
都是
WRAP_CONTENT
,则使用屏幕尺寸。
如果
width
height
中至少有一个值<=0并且不是
WRAP_CONTENT
,那么就会在布局的时候添加一个
OnPreDrawListener
监听ImageView的尺寸

Glide对
WRAP_CONTENT
的支持并不好,所以尽量不要用。

那么如何在运行修改ImageView尺寸呢?


方法一 继承ImageViewTarget

我这里指定的View的类型是ImageView,资源类型是Bitmap,可根据需要修改,
onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition)
方法中可以通过bitmap获取图片的尺寸。
public class CustomImageViewTarget extends ImageViewTarget<Bitmap> {

private int width, height;

public CustomImageViewTarget(ImageView view) {
super(view);
}

public CustomImageViewTarget(ImageView view, int width, int height) {
super(view);
this.width = width;
this.height = height;
}

@Override
public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
super.onResourceReady(bitmap,transition);
}

@Override
protected void setResource(@Nullable Bitmap resource) {
view.setImageBitmap(resource);
}

@Override
public void getSize(SizeReadyCallback cb) {
if (width > 0 && height > 0) {
cb.onSizeReady(width, height);
return;
}
super.getSize(cb);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

使用:
GlideApp.with(context)
.asBitmap()
.load(url)
.dontAnimate()
.placeholder(R.drawable.img_default)
.into(new CustomImageViewTarget(imageview, 300, 300));
1
2
3
4
5
6


方法二 使用override()

GlideApp.with(mContext)
.load(url)
.override(width,height)
.into(view);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: