詳解Glide最新版V4使用指南
概述
Glide是一個Android的圖片加載和緩存庫,它主要專注于大量圖片的流暢加載,Glide幾乎可以勝任任何你需要使用到圖片從網(wǎng)絡(luò)拉取,壓縮,顯示的場景。
本文主要基于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'
}
Android Studio3.0使用:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.3.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
}
使用implementation還是api需要視情況而定,implementation只能用于當前module,如果在庫中以這種方式設(shè)置依賴,那么在app的module是引用不到的,但是api可以,api相當于compile。
在proguard.pro/proguard.cfg中添加混淆:
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
2 基本用法
大多數(shù)情況下加載圖片只需要一行代碼:
Glide.with(fragment) .load(myUrl) .into(imageView);
取消加載也很簡單:
Glide.with(fragment).clear(imageView);
實際上你并不需要取消加載。。。
因為當你在with方法中傳入的Activity或Fragment被銷毀的時候,Glide會自動取消加載并且回收所有的加載過程中所使用的資源。
3 注解(V4新特性)和自定義方法
Glide使用了annotation processor來生成API,允許應(yīng)用修改RequestBuilder、RequestOptions和任意的包含在單一流式API庫中的方法。這是V4的特性,運用注解后使用起來更方便:
GlideApp.with(fragment) .load(myUrl) .placeholder(R.drawable.placeholder) .fitCenter() .into(imageView);
Glidev4中的Glide.with().load()后沒有之前版本的fitCenter和placeholder這樣的方法,但是GlideApp有,可以直接在builder中使用。GlideApp可以代替之前版本的Glide開頭。
這樣做的目的是:
1.對于library項目來講可以使用自定義方法繼承Glide的API
2.對于應(yīng)用來講,在繼承Glide的API后,可以通過添加自定義方法。
雖然你也可以手動繼承RequestOptions,但是顯然這樣做更加麻煩,也破壞了流式API特性。
3.1 在項目中實現(xiàn)AppGlideModule:
@GlideModule
public class CustomGlideModule extends AppGlideModule {}
這個類實現(xiàn)必須要有@GlideModule注解,如果你添加的方法失效,那就檢查下這里。
如果是library就實現(xiàn)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());
}
}
OkHttpUrlLoader是Glide的OKHttp擴展庫中的類,如果需要使用Glide的實現(xiàn),可以在依賴中添加:
compile 'com.github.bumptech.glide:okhttp3-integration:4.3.1'
Android Studio 3.0
implementation 'com.github.bumptech.glide:okhttp3-integration:4.3.1'
添加完依賴不需要自己實現(xiàn)OkHttpLibraryGlideModule類,庫中已經(jīng)自帶了,會自動使用OKHttp的。
然后編譯工程可以發(fā)現(xiàn)在build中生成了四個類:

3.2 GlideExtension
為了添加新的方法,修改已有的方法或者添加對其他類型格式的支持,你需要在擴展中使用加了注解的靜態(tài)方法。
GlideOption用來添加自定義的方法,GlideType用來支持新的格式。
3.2.1 GlideOption
先新建一個CustomGlideExtension類:
@GlideExtension
public class CustomGlideExtension {
//縮略圖的最小尺寸,單位:px
private static final int MINI_THUMB_SIZE = 100;
/**
* 將構(gòu)造方法設(shè)為私有,作為工具類使用
*/
private CustomGlideExtension() {
}
/**
* 1.自己新增的方法的第一個參數(shù)必須是RequestOptions options
* 2.方法必須是靜態(tài)的
* @param options
*/
@GlideOption
public static void miniThumb(RequestOptions options) {
options
.fitCenter()
.override(MINI_THUMB_SIZE);
}
}
編譯工程,打開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();
}
...
}
現(xiàn)在可以使用你自定義的方法了:
GlideApp.with(fragment) .load(url) .miniThumb(thumbnailSize) .into(imageView);
3.2.2 GlideType
以添加對GIF格式的支持為例,只是舉例,實際上API中已經(jīng)支持了。
在剛才的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);
}
}
編譯工程,打開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;
}
}
現(xiàn)在可以使用你添加的類型了:
GlideApp.with(fragment) .asGIF() .load(url) .into(imageView);
4 占位符
占位符就是請求的圖片沒加載出來時顯示的默認圖片。
Glide支持三種不同情況下的占位符:
- Placeholder 請求圖片加載中
- Error 請求圖片加載錯誤
- Fallback 請求url/model為空
設(shè)置占位符:
GlideApp.with(fragment) .load(url) .placeholder(R.drawable.placeholder) .error(new ColorDrawable(Color.RED)) .fallback(new ColorDrawable(Color.GREY)) .into(view);
之后的顯示優(yōu)先級,我畫了個流程圖。

5 Options
5.1 RequestOptions
Glide中的大多請求參數(shù)都可以通過RequestOptions類和apply()方法來設(shè)置。
Glide中的請求參數(shù)主要有:
- Placeholders 占位符
- Transformations 變換
- Caching Strategies 緩存策略
- 組件特定參數(shù):編碼質(zhì)量,解碼參數(shù)等。
比如,要將圖片的顯示方式設(shè)為CenterCrop,你可以這么做:
import static com.bumptech.glide.request.RequestOptions.centerCropTransform; Glide.with(fragment) .load(url) .apply(centerCropTransform(context)) .into(imageView);
但是其實完全可以在layout文件中設(shè)置ImageView為android:scaleType="centerCrop",Glide會自動根據(jù)這個屬性設(shè)置圖片的顯示方式。
apply方法可以調(diào)用多次,但是如果兩次apply存在沖突的設(shè)置,會以最后一次為準。
5.2 TransitionOptions
TransitionOptions決定圖片加載完成如何從占位符圖片(或者之前的圖片)過渡。
- 淡入
- 交叉淡入
- 不過渡
Glide.with(fragment) .load(url) .transition(DrawableTransitionOptions.withCrossFade()) .into(view);
注意
TransitionOptions是和你要加載的資源的類型綁定的,也就是說,如果你請求一張位圖(Bitmap),你就需要使用BitmapTransitionOptions,而不是DrawableTransitionOptions。因此,你請求的這張位圖,你需要用簡單的淡入,而不能用 交叉淡入(DrawableTransitionOptions.withCrossFade())。
如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions
5.3 RequestBuilder
作用:
- 指定加載類型。asBitmap()、asGif()、asDrawable()、asFile()。
- 指定要加載url/model。
- 指定要加載到那個View。
- 指定要應(yīng)用的RequestOption
- 指定要應(yīng)用的TransitionOption
- 指定要加載的縮略圖
那么如何得到RequestBuilder呢?
RequestBuilder<Drawable> requestBuilder = Glide.with(fragment);
默認得到一個Drawable RequestBuilder,如果要指定類型為Bitmap,可以這樣寫:
RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap();
應(yīng)用RequestOptions
RequestBuilder<Drawable> requestBuilder = Glide.with(fragment); requestBuilder.apply(requestOptions); requestBuilder.transition(transitionOptions);
RequestBuilder也可以重復(fù)使用:
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);
}
6 Transformations
Glide會自動讀取ImageView的縮放類型,所以一般在layout文件指定scaleType即可。
CenterCrop, CenterInside, CircleCrop, FitCenter, RoundedCorners
Glide支持在java代碼中設(shè)置這些縮放類型:
- CenterCrop 縮放寬和高都到達View的邊界,有一個參數(shù)在邊界上,另一個參數(shù)可能在邊界上,也可能超過邊界
- CenterInside 如果寬和高都在View的邊界內(nèi),那就不縮放,否則縮放寬和高都進入View的邊界,有一個參數(shù)在邊界上,另一個參數(shù)可能在邊界上,也可能在邊界內(nèi)
- CircleCrop 圓形且結(jié)合了CenterCrop的特性
- FitCenter 縮放寬和高都進入View的邊界,有一個參數(shù)在邊界上,另一個參數(shù)可能在邊界上,也可能在邊界內(nèi)
- RoundedCorners 圓角
有三種用法:
1 使用RequestOptions
RequestOptions options = new RequestOptions(); options.centerCrop(); Glide.with(fragment) .load(url) .apply(options) .into(imageView);
2 使用RequestOptions中的transform方法
Glide.with(fragment) .load(url) .apply(RequestOptions.fitCenterTransform()) .into(imageView);
3 V4特性
GlideApp.with(fragment) .load(url) .fitCenter() .into(imageView);
第三種方法最簡便,推薦。
多個變換
Glide.with(fragment) .load(url) .transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation()) .into(imageView);
7 Transitions(動畫)
普通動畫
Glide中的過渡動畫是指占位符到請求圖片或縮略圖到完整尺寸請求圖片的動畫。過渡動畫只能針對單一請求,不能跨請求執(zhí)行。
過渡動畫執(zhí)行時機:
1.圖片在磁盤緩存
2.圖片在本地
3.圖片在遠程
如果圖片在內(nèi)存緩存上是不會執(zhí)行過渡動畫的。如果需要在內(nèi)存緩存上加載動畫,可以這樣:
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) {
//當圖片位于內(nèi)存緩存時,glide默認不會加載動畫
imageView.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
}
return false;
}
}).fitCenter().transition(GenericTransitionOptions.with(R.anim.fade_in)).into(imageView);
通常的用法如下:
Glide.with(fragment) .load(url) .transition(DrawableTransitionOptions.withCrossFade()) .into(view);
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.實現(xiàn)TransitionFactory
2.重寫build()
可以控制圖片在內(nèi)存緩存上是否執(zhí)行動畫。
具體寫法參考DrawableCrossFadeFactory,然后調(diào)用TransitionOptions的with(TransitionFactory transitionFactory)加載。
8 基本配置
8.1 配置內(nèi)存緩存
Glide會自動合理分配內(nèi)存緩存,但是也可以自己手動分配。
方法一
通過MemorySizeCalculator設(shè)置
@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()));
}
}
setMemoryCacheScreens設(shè)置MemoryCache應(yīng)該能夠容納的像素值的設(shè)備屏幕數(shù),說白了就是緩存多少屏圖片,默認值是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));
}
}
方法三
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setMemoryCache(new CustomGlideMemoryCache());
}
}
自己實現(xiàn)MemoryCache接口。
清理內(nèi)存緩存,在主線程調(diào)用:
GlideApp.get(context).clearMemory();
在使用的時候,可以跳過內(nèi)存緩存:
GlideApp.with(getActivity()) .load(url) .skipMemoryCache(true) .dontAnimate() .centerCrop() .into(imageView);
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));
}
}
用法如上,可以指定緩存在內(nèi)部存儲或外部存儲,也可以指定緩存大小和文件夾。
自定義磁盤緩存
@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();
}
});
}
}
自己實現(xiàn)DiskCache接口。
清理磁盤緩存,在子線程調(diào)用:
GlideApp.get(context).clearDiskCache();
加載圖片時設(shè)置磁盤緩存策略:
GlideApp.with(getActivity()) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .dontAnimate() .centerCrop() .into(imageView);
默認的策略是DiskCacheStrategy.AUTOMATIC
DiskCacheStrategy有五個常量:
- DiskCacheStrategy.ALL 使用DATA和RESOURCE緩存遠程數(shù)據(jù),僅使用RESOURCE來緩存本地數(shù)據(jù)。
- DiskCacheStrategy.NONE 不使用磁盤緩存
- DiskCacheStrategy.DATA 在資源解碼前就將原始數(shù)據(jù)寫入磁盤緩存
- DiskCacheStrategy.RESOURCE 在資源解碼后將數(shù)據(jù)寫入磁盤緩存,即經(jīng)過縮放等轉(zhuǎn)換后的圖片資源。
- DiskCacheStrategy.AUTOMATIC 根據(jù)原始圖片數(shù)據(jù)和資源編碼策略來自動選擇磁盤緩存策略。
8.3 禁止解析Manifest文件
主要針對V3升級到v4的用戶,可以提升初始化速度,避免一些潛在錯誤。
@GlideModule
public class CustomGlideModule extends AppGlideModule {
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
8.4 View尺寸
Glide對ImageView的width和height屬性是這樣解析的:
- 如果width和height都大于0,則使用layout中的尺寸。
- 如果width和height都是WRAP_CONTENT,則使用屏幕尺寸。
- 如果width和height中至少有一個值<=0并且不是WRAP_CONTENT,那么就會在布局的時候添加一個OnPreDrawListener監(jiān)聽ImageView的尺寸
Glide對WRAP_CONTENT的支持并不好,所以盡量不要用。
那么如何在運行修改ImageView尺寸呢?
方法一 繼承ImageViewTarget
我這里指定的View的類型是ImageView,資源類型是Bitmap,可根據(jù)需要修改,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);
}
}
使用:
GlideApp.with(context) .asBitmap() .load(url) .dontAnimate() .placeholder(R.drawable.img_default) .into(new CustomImageViewTarget(imageview, 300, 300));
方法二 使用override()
GlideApp.with(mContext) .load(url) .override(width,height) .into(view);
獲取bitmap
如果只想用Glide解析url獲取一個bitmap,然后自己對其進行處理,可以使用SimpleTarget<Z>,
/**
* Constructor for the target that uses {@link Target#SIZE_ORIGINAL} as the target width and
* height.
*/
public SimpleTarget() {
this(SIZE_ORIGINAL, SIZE_ORIGINAL);
}
/**
* Constructor for the target that takes the desired dimensions of the decoded and/or transformed
* resource.
*
* @param width The width in pixels of the desired resource.
* @param height The height in pixels of the desired resource.
*/
public SimpleTarget(int width, int height) {
this.width = width;
this.height = height;
}
SimpleTarget也可以指定寬和高,用法示例:
Glide.with(itemView.getContext()).asBitmap().load(url).into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
}
});
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解析:繼承ViewGroup后的子類如何重寫onMeasure方法
本篇文章是對繼承ViewGroup后的子類如何重寫onMeasure方法進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Android實現(xiàn)頂部導(dǎo)航欄可點擊可滑動效果(仿微信仿豆瓣網(wǎng))
這篇文章主要介紹了 Android實現(xiàn)頂部導(dǎo)航欄可點擊可滑動效果(仿微信仿豆瓣網(wǎng)),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03
Android開發(fā)實現(xiàn)Fragment監(jiān)聽返回鍵事件功能的方法
這篇文章主要介紹了Android開發(fā)實現(xiàn)Fragment監(jiān)聽返回鍵事件功能的方法,結(jié)合實例形式分析了Android使用Fragment監(jiān)聽并屏蔽返回鍵按鈕的實現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
Android FaceDetector實現(xiàn)人臉檢測功能
這篇文章主要為大家詳細介紹了Android FaceDetector實現(xiàn)人臉檢測功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android實現(xiàn)TextView顯示HTML加圖片的方法
這篇文章主要介紹了Android實現(xiàn)TextView顯示HTML加圖片的方法,結(jié)合實例形式分析了TextView控件顯示網(wǎng)絡(luò)圖片的相關(guān)操作技巧,需要的朋友可以參考下2016-07-07
Android 本地廣播和強制下線功能的實現(xiàn)代碼
這篇文章主要介紹了Android 本地廣播和強制下線功能的實現(xiàn)代碼,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
深入解讀Android開發(fā)中Activity的生命周期
這篇文章主要介紹了Android開發(fā)中Activity的生命周期,包括Activity的停止和銷毀等重要內(nèi)容,非常推薦!需要的朋友可以參考下2015-12-12

