從接觸應(yīng)用層開(kāi)發(fā)開(kāi)始,圖片相關(guān)的功能一直都是Android開(kāi)發(fā)人員比較關(guān)注的問(wèn)題族铆,從最開(kāi)始的ImageLoader叶堆,到Square公司開(kāi)發(fā)的Picasso圖片加載框架包斑,再到如今的主流圖片加載框架Glide干旧,其實(shí)我們都知道這幾個(gè)圖片框架的核心都離不開(kāi)緩存渠欺,內(nèi)存緩存和磁盤緩存,兩者結(jié)合極大程度的提高了圖片的加載效率椎眯。但是我們從框架中學(xué)到遠(yuǎn)不止這些挠将,接下來(lái)我會(huì)分幾篇來(lái)分析下Glide框架到底為何能成為主流的圖片加載框架呢,首先看看它的一些常用的使用方式编整。
基本使用
本次我們使用glide4.9.0版本來(lái)講述功能和代碼捐名,首先需要在gradle中配置:
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}
dependencies {
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
}
不要忘記了添加權(quán)限~
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
混淆文件:
-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.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# target API 低于 Android API 27
-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
常規(guī)加載圖片
Glide.with(this)
.load(imgUrl)
.into(imageView);
絕大多數(shù)加載圖片的功能都能用上面一行代碼解決,除了部分需要特定場(chǎng)景的需求闹击,則需要用到Glide的其他功能,我們來(lái)看下加載的效果圖
加載占位圖
Glide官方提供的占位圖有三種成艘,分別是Placeholder赏半,Error,F(xiàn)allBack淆两。
- Placeholder主要用于當(dāng)前我們加載的圖片還未成功顯示的時(shí)候作為當(dāng)前圖片的臨時(shí)顯示断箫,如果請(qǐng)求圖片一直沒(méi)有成功,并且沒(méi)有設(shè)置Error和FallBack占位圖秋冰,那么Placeholder占位圖則會(huì)一直顯示仲义。
- Error則是用于當(dāng)我們的圖片加載失敗了會(huì)顯示,當(dāng)沒(méi)有設(shè)置FallBack的時(shí)候剑勾,那么Error占位圖則會(huì)一直顯示埃撵。
- FallBack則是表示如果所加載的圖片文件或者URL為空,那么這個(gè)時(shí)候加載的就是FallBack占位圖虽另,相當(dāng)于是view加載沒(méi)有獲取到圖片的url時(shí)候加載的默認(rèn)圖暂刘。
Placeholder占位圖的使用
Glide.with(this)
.load(url)
.placeholder(new ColorDrawable(Color.GREEN))
.into(view);
這里我們給Placeholder設(shè)置本地drawable資源和設(shè)置背景色都行,為了省時(shí)間我設(shè)置的背景色捂刺,我們來(lái)看看添加背景色占位圖后的效果谣拣,這里為了能夠清晰的看出效果,選擇了比較明亮的原諒色族展,正常的開(kāi)發(fā)中使用較多的還是灰白色的占位圖森缠。
Error占位圖的使用
Glide.with(this)
.load(url)
.error(new ColorDrawable(Color.RED))
.into(view);
這里給Error設(shè)置的紅色,功能和Placeholder一樣仪缸,我關(guān)閉了網(wǎng)絡(luò)請(qǐng)求權(quán)限贵涵,顯示的則是一直請(qǐng)求出錯(cuò)的占位圖。
FallBack占位圖的使用
Glide.with(this)
.load(url)
.fallback(new ColorDrawable(Color.BLUE))
.into(view);
RequestOptions
通常情況下,一般的鏈?zhǔn)秸{(diào)用能滿足我們的需求独悴,但是glide也提供了這樣的功能例书,當(dāng)我們加載多個(gè)img時(shí),必定需要多次去使用glide和設(shè)置加載的選項(xiàng)刻炒,那么如果這些選項(xiàng)存在公共的設(shè)置决采,應(yīng)該可以提取出來(lái),那么這是options的作用了坟奥,單獨(dú)提取出來(lái)也使代碼更簡(jiǎn)潔树瞭,我們來(lái)看看使用方式:
RequestOptions requestOptions = new RequestOptions()
.error(new ColorDrawable(Color.RED))
.centerCrop();
Glide.with(this)
.load(url)
.apply(requestOptions)
.into(view);
TransitionOptions
TransitionOptions一般用于當(dāng)圖片加載完成后,如果設(shè)置了占位圖爱谁,那么是獲取到的圖片替換掉占位圖的一個(gè)過(guò)度動(dòng)畫(huà)晒喷,例如淡入淡出,羨慕就嘗試使用淡入的效果設(shè)置加載完成后TransitionOptions的設(shè)置访敌;看運(yùn)行結(jié)果和Placeholder占位圖的綠色背景比較凉敲,明顯在設(shè)置圖片的時(shí)候有了 一個(gè)緩慢的過(guò)渡,這樣避免了圖片閃過(guò)的場(chǎng)景寺旺。
Glide.with(this)
.load(url)
.placeholder(new ColorDrawable(Color.GREEN))
.transition(withCrossFade())
.into(view);
RequestBuilder
RequestBuilder相對(duì)比較靈活爷抓,它攜帶了一個(gè)圖片加載的幾個(gè)重要元素,包括請(qǐng)求的rul和常規(guī)的設(shè)置(占位圖阻塑,Options蓝撇,縮略圖等),針對(duì)不同的需求陈莽,我們同樣也能單獨(dú)先創(chuàng)建RequestBuilder渤昌,然后再去load(url)和into(view),看看下面的例子:
RequestBuilder<Drawable> requestBuilder = Glide.with(this).asDrawable();
requestBuilder.load(url).into(view);
Thumbnail
Thumbnail表示縮略圖走搁,當(dāng)我們請(qǐng)求圖片還未能加載的時(shí)候独柑,可以選擇優(yōu)先展示另一個(gè)縮略圖的圖片url,直到原圖片展示成功私植,這樣對(duì)于用戶來(lái)說(shuō)是友好的群嗤。
Glide.with(this)
.load(url)
.thumbnail(Glide.with(this)
.load(thumbnailUrl))
.into(imageView);
如果加載的圖片只有一個(gè)url,而沒(méi)有縮略圖的url兵琳,那么你可以像下面這么做狂秘,在thumbnail里面設(shè)置圖片的寬高,則執(zhí)行加載指定寬高的縮略圖躯肌,最終效果如下者春,可以清晰的看到在顯示原圖之前有一個(gè)縮略圖的過(guò)渡,這樣看起來(lái)效果是不是比最初的直接load好多了呢清女?
Glide.with(this)
.load(url)
.placeholder(new ColorDrawable(Color.GREEN))
.transition(withCrossFade())
.thumbnail(Glide.with(this).load(url).override(60))
.into(imageView);
SizeMultiplier
如果你想加載一張圖片的縮略圖钱烟,那么sizeMultiplier表示為這張圖縮小多少比例,如下設(shè)置為縮小四分之一
Glide.with(this)
.load(url)
.thumbnail(/*sizeMultiplier*/ 0.25f)
.into(imageView);
請(qǐng)求失敗后再次請(qǐng)求
這種做法類似于thumbnail,當(dāng)mainurl請(qǐng)求失敗后拴袭,則會(huì)去請(qǐng)求twourl读第,當(dāng)我們同時(shí)設(shè)置了thumbnail請(qǐng)求,那么它只會(huì)在mainurl請(qǐng)求失敗后去再次請(qǐng)求拥刻;
Glide.with(this)
.load(mainurl)
.error(Glide.with(this)
.load(twourl))
.into(imageView);
Transformations
通常Transformations 用來(lái)對(duì)獲取的圖片資源進(jìn)行裁剪怜瞒、縮放、GIF動(dòng)畫(huà)轉(zhuǎn)換等操作般哼,一般情況下Glide提供了CenterCrop吴汪、FitCenter、CircleCrop的內(nèi)置轉(zhuǎn)換蒸眠,單獨(dú)使用或者結(jié)合RequestOptions使用漾橙,如下使用:
Glide.with(this)
.load(mainurl)
.centerCrop()
.into(imageView);
如果使用多個(gè)轉(zhuǎn)換,MultiTransformation可以省略楞卡,CustomTransformation為自定義的Transformation霜运,MultiTransformation構(gòu)造函數(shù)的傳入?yún)?shù)的順序,決定了這些轉(zhuǎn)換的實(shí)現(xiàn)順序蒋腮,如果效果重合觉渴,那么后面的參數(shù)效果會(huì)覆蓋前面的效果,那么需要如下使用方式:
Glide.with(fragment)
.load(url)
.transform(new MultiTransformation(new centerCrop(), new CustomTransformation())
.into(imageView);
如果對(duì)圖片有特定的轉(zhuǎn)換需求徽惋,那么需要定制化transformation,Glide為我們提供了許多Transformation座韵,假如我們需要對(duì)bitmap特定轉(zhuǎn)化险绘,那么可以使用BitmapTransformation,使用方法如下:
public class CustomTrans extends BitmapTransformation {
private static final String ID = "com.glide.demo.CustomTrans";
private static String ID_BYTES = null;
static {
try {
ID_BYTES = String.valueOf(ID.getBytes(STRING_CHARSET_NAME));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
return toTransform;
}
//操作圖片,得到新的bitmap
return Bitmap.createScaledBitmap(toTransform, outWidth, outHeight, /*filter=*/ true);
}
/**
* 下面三個(gè)方法必須重寫(xiě),將當(dāng)前類的hashcode作為當(dāng)前轉(zhuǎn)換的bitmap的key
* 便于存儲(chǔ)到磁盤和內(nèi)存,那么下次獲取則通過(guò)當(dāng)前key獲取緩存
* @param
*/
@Override
public boolean equals(Object o) {
return o instanceof CustomTrans;
}
@Override
public int hashCode() {
return ID.hashCode();
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(Byte.parseByte(ID_BYTES));
}
}
緩存設(shè)置
Glide.with(this)
.load(mainurl)
//跳過(guò)內(nèi)存緩存
.skipMemoryCache(true)
//緩存所有版本的圖像
.diskCacheStrategy(DiskCacheStrategy.ALL)
//跳過(guò)磁盤緩存
.diskCacheStrategy(DiskCacheStrategy.NONE)
//只緩存原來(lái)分辨率的圖片
.diskCacheStrategy(DiskCacheStrategy.DATA)
//只緩存最終的圖片
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(imageView);
總結(jié)
關(guān)于一些常規(guī)的Glide使用方法暫時(shí)總結(jié)到這里匹摇,后面會(huì)陸續(xù)再補(bǔ)充的更全面耗溜,本篇文章也會(huì)陸續(xù)更新,下一章我們一起看下Glide源碼驹碍,一共會(huì)分幾個(gè)層面來(lái)解析,如有什么疑問(wèn)也能提出,隨時(shí)修正和改進(jìn)呐芥。最后放出官方文檔和源碼地址:
Github地址:https://github.com/bumptech/glide
官方文檔:http://bumptech.github.io/glide/
官方文檔中文版:https://muyangmin.github.io/glide-docs-cn/