一篇好文,助你上手 Glide

版權(quán)聲明:

本賬號發(fā)布文章均來自公眾號狐赡,承香墨影(cxmyDev)撞鹉,版權(quán)歸承香墨影所有。

未經(jīng)允許,不得轉(zhuǎn)載鸟雏。

一享郊、前言

Glide 現(xiàn)在大范圍的使用在各種商業(yè)項目中,而對于一般而言孝鹊, GlideApi 封裝的非常好炊琉,多數(shù)情況下我們只需要使用它,在使用的基礎之上惶室,才考慮如何了解它温自。

本文的目的是讓你如何快速上手 Glide 3.x ,來快速投入開發(fā)皇钞,本文力求做到快速上手悼泌,所以只講在上手的時候,你需要關注的夹界。

本文最開始只是想做一個簡短的快速上手的教程馆里,但是在寫的過程中,越寫越長可柿。但是內(nèi)容都是我覺得必須要講清楚的鸠踪,所以如果想要快速上手 Glide,請耐心閱讀复斥。

二营密、簡單使用

2.1 什么是 Glide ?

既然要用到 Glide 目锭,那就先簡單的介紹一下 Glide 评汰。

Glide 簡單來說就是一個 Google 主導的圖片加載開源庫。它穩(wěn)定痢虹、速度快被去、可自適應圖片尺寸、支持眾多格式奖唯、支持加載不同來源的圖片惨缆、內(nèi)存和磁盤緩存的優(yōu)化。這些丰捷,都是它的好處(當然不止這些)坯墨,這里就不一一細說了。

你只需要知道瓢阴,它是一款主流的圖片加載庫即可畅蹂,它包含了你能想到的所有功能,并且支持擴展荣恐。

Glide 的 Github 地址:

https://github.com/bumptech/glide

2.2 在項目內(nèi)集成 Glide

雖然它已經(jīng)到 v4.x 了,但是本文還是就最常用的 v3.8.0 版本的集成,做一個簡單的介紹叠穆。

集成的方式有多種少漆,可以直接引用 jar 包,也可以使用 Maven硼被,這里還是使用主流的 Gradle 來集成它示损。


如果需要配置混淆忽冻,還需要在混淆文件中區(qū)分 Glide 培慌。


Glide 只是一個圖片加載庫全庸,而大多數(shù)情況下蟹但,我們的圖片均來自互聯(lián)網(wǎng)臀防。所以它的網(wǎng)絡請求庫悉患,其實是可以配置的忆植,Glide 可以支持 OkHttp 和 Volley 量蕊。

這里使用的另外一個優(yōu)秀的網(wǎng)絡請求庫 OkHttp 來做支持起暮。


配好 Glide 卖氨,我們就可以開始使用它了。

2.3 最簡單的使用

Glide 是支持鏈式調(diào)用的负懦,但是它不是簡單的在每個方法中筒捺,返回 this ,它更復雜一些纸厉,后面會講到系吭,所以通常使用它只需要使用一條語句即可。


這是一個最簡單的 Glide 的 Demo颗品,使用它即可從網(wǎng)絡上加載一張圖片到一個 ImageView 中去顯示肯尺。

三、Glide 需要了解的內(nèi)容

前面的例子可以看到抛猫,實際上 Glide 的鏈式調(diào)用蟆盹,它的主要方法就是三個,先來簡單看看他們.

  • with : 主要是傳遞一個 Glide 可用的 Context闺金,它和生命周期相關逾滥。
  • load:接收一個待加載的圖片資源,可支持多種格式败匹。
  • into寨昙;指定加載的圖片的最終使用目標對象,例如可以是一個 ImageView掀亩。

這三個主要的部分舔哪,貫穿了 Glide 使用的主要重點內(nèi)容,接下來讓我們好好看看他們槽棍。

3.1 with()

前面提到捉蚤,這里的 with() 方法用于給 Glide 傳遞一個 Context 對象抬驴,它可以支持多種 Context。


對于 with 而言缆巧,它會返回一個 RequestManager 用于管理請求布持,而它接收的這些不同的 Context ,并不是為了讓我們方便使用陕悬,而是會對當前 Context 的生命周期做監(jiān)聽题暖,來管理 Glide 自身的圖片加載的請求。

舉個例子:當使用 with(Activity) 的時候捉超,如果此時當前 Activity 被關閉掉了胧卤,那么 Glide 就會將這個 Activity 下所有的圖片請求停止掉。也就是實現(xiàn)了 Glide 和 頁面聲明周期的綁定拼岳,來優(yōu)化 Glide 自身的請求策略枝誊。

所以,在使用 Glide 的時候裂问,盡量使用當前頁面的 Activity 侧啼,而非直接傳遞一個 Context 進去。盡量小的選擇 Context 的范圍堪簿,他們的推薦優(yōu)先級為:

Fragment > Activity > Context

3.2 load()

load() 方法痊乾,就是去指定一個待加載的資源,它支持很多格式和資源種類椭更。例如:網(wǎng)絡地址哪审、本地文件、Drawable 等虑瀑,它都是可以做到很好的加載的湿滓。

load() 方法,并不是在 Glide 中舌狗,前面也提到 with() 會返回一個 RequestManager 對象叽奥,load() 方法在它內(nèi)部實現(xiàn)。


具體 load() 方法痛侍,支持的資源種類朝氓,可以看到它方法的重載,基本上我們能想到的主届,它都支持赵哲。

有意思的是 load() 方法,它返回的是另外一個 DrawableTypeRequest 對象君丁。

3.3 into()

into() 方法枫夺,用于指定加載的圖片資源,最終給誰來使用绘闷。這個沒什么好說的橡庞,加載的圖片较坛,最終一定是用來顯示的,所以它需要指定一個使用圖片的對象毙死。

into() 實際上是 DrawableTypeRequest 中的方法燎潮,DrawableTypeRequest 是一個多層繼承的類喻鳄,它實際上自己是沒有對 into() 方法的實現(xiàn)的扼倘,大部分實現(xiàn)都是在其父類 DrawableRequestBuilder 和 父類的父類 GenericRequestBuilder 中的,但是這并不影響我們使用它除呵。


從方法的簽名再菊,可以看到 into() 不只是可以接受一個 ImageView ,也可以是一些其他的什么颜曾。這也很好理解纠拔,在項目內(nèi),也不僅僅只有 ImageView 可以用來顯示圖片泛豪,View 的 background 也是可以用于顯示圖片的稠诲。

除了 ImageView 前面已經(jīng)介紹過了,直接使用即可诡曙。剩下的后面會有講到臀叙。

四、Glide 的使用細節(jié)

既然 Glide 使用過程中价卤,最重要的三個方法已經(jīng)介紹過了劝萤,他們是 Glide 能完成功能的基礎,接下來慎璧,就開始介紹 Glide 的使用細節(jié)床嫌,來見證 Glide 的強大。

本節(jié)介紹的 Glide 的使用細節(jié)胸私,基本上都是與 load() 方法返回的 DrawableTypeRequest 對象進行操作厌处,對其進行一些配置。

4.1 不同狀態(tài)的占位圖

在圖片加載的過程中岁疼,會經(jīng)歷過多過程阔涉,例如:加載中、加載失敗等等五续,在這些過程中洒敏,其實是可以為暫時為 ImageView 設置一個占位的的,來定制加載中疙驾、加載失敗這種狀態(tài)的顯示效果凶伙。

Glide 定制的占位圖,有三種:

  • placeholder :指定加載前顯示的圖片資源它碎。
  • error:指定加載失敗顯示的圖片資源函荣。
  • fallback:指定傳遞加載資源為 null 的時候显押,顯示的圖片資源。


例如上面的例子中傻挂,其實 fallback() 是無需指定的乘碑,因為 imageUri 是不可能為 null 的。而其他的金拒,都會在不同的階段顯示出來兽肤,加載前會顯示 load_placeholder ,如果加載失敗了绪抛,會顯示 load_error 资铡。

注意,不同狀態(tài)的占位圖幢码,實際上是一種容錯的表現(xiàn)笤休,所以只能用于加載一個『本地資源』,允許傳遞一個 @DrawableId 或者 Drawable 對象症副。

4.2 縮放控制

某些時候店雅,因為圖片的尺寸和控件的尺寸,不一定能匹配贞铣,所以會對圖片的顯示效果闹啦,進行一些縮放,而大多數(shù)情況下咕娄,這種默認的縮放策略亥揖,并不是我們想要的。

Glide 提供了一些方法來控制縮放的效果圣勒。

  • centerCrop()
  • fitCenter()

這兩個方法和 ImageView.setScaleType() 中傳遞的參數(shù)效果類似费变,就不再一一贅述了。

4.3 緩存控制

現(xiàn)在基本上所有的圖片加載庫圣贸,都是遵照三級緩存的策略:網(wǎng)絡挚歧、磁盤、內(nèi)存吁峻。Glide 也是如此滑负,并且默認情況下,為了更好的體驗用含,這些緩存都是全部開啟的矮慕。

就 Glide 的緩存策略而言,其實我們也是有辦法去調(diào)整的啄骇。

對于內(nèi)存緩存而言痴鳄,只有有或者沒有的情況,所以 Glide 只提供了一個 skipMemoryCache() 方法缸夹,它可以傳遞一個 Boolean 的值痪寻,用于指定是否跳過磁盤緩存螺句,默認情況下是 false ,表示需要內(nèi)存緩存橡类。

但是對于磁盤緩存蛇尚,就會更復雜一些。Glide 為了保證效率顾画,實際上默認情況下是會去緩存多種尺寸的圖片在磁盤上的取劫,也就是說,對于同一個 Uri亲雪,如果你在不同尺寸的 ImageView 中使用到它了勇凭,默認情況下,在你設備的磁盤上义辕,也會有多張不同尺寸的圖片。這樣是為了下次加載的時候寓盗,速度更快灌砖,無需再對原圖進行處理,是一種以空間換效率的策略傀蚌。

而如果我們需要對磁盤緩存進行調(diào)節(jié)基显,就需要使用 diskCacheStrategy() 方法來改變它,前面提到它是一種比較復雜的策略善炫,所以無法簡單的使用一個 Boolean 值就完成了撩幽。它需要傳遞一個 DiskCacheStrategy 的枚舉類型。


可以看到箩艺,它實際上是通過兩個參數(shù)來標記磁盤緩存的策略的窜醉。

  • ALL:緩存所有類型的圖片(默認行為)。
  • NONE :禁用磁盤緩存艺谆。
  • SOURCE : 只緩存全尺寸的原圖榨惰。
  • RESULT :只緩存壓縮后的圖片。

所以具體使用那種静汤,就需要看當前加載的圖片屬于哪一種了琅催。


上面的例子就是忽略內(nèi)存緩存,并且磁盤只緩存原圖的策略虫给。

4.4 加載優(yōu)先級

對于同一個頁面藤抡,如果需要在多個地方都加載線上圖片,必然會存在一個優(yōu)先級的問題抹估。例如:正常來說缠黍,背景圖是比其他圖片優(yōu)先級更高的圖片。

Glide 是可以在加載中棋蚌,對當前加載的圖片嫁佳,調(diào)整加載的優(yōu)先級的挨队。需要使用 priority() 方法,它可以接受一個 Priority 的枚舉類型蒿往,包含四種值:LOW(低)盛垦、HIGH(高)、NORMAL(普通)瓤漏、IMMEDIATE(立即)腾夯。

可以在我們需要的時候,對其進行配置蔬充,但是它并不影響用 Glide 加載的圖片的顯示順序蝶俱,只是用于 Glide 在加載圖片的時候一個優(yōu)化請求的參數(shù)而已,并不影響最終顯示的順序饥漫。

4.5 載入動畫

Glide 在顯示圖片的時候榨呆,為了讓顯示效果不那么突兀,會以一種更柔和的方式去顯示庸队,就會在加載的時候給一個動畫效果积蜻,它可以使用 crossFade() 方法進行配置,如果不特殊處理彻消,默認它是開啟的竿拆,并且本身默認動畫的時長是 300ms


crossFade() 也是有多個重載的宾尚,主要是為了指定動畫以及動畫的時長丙笋。如果有心,也可以看看 crossFade() 的源碼煌贴,它實際上只是對 animate() 方法的一個包裝而已御板,后面會講到。


crossFade() 的效果是默認開啟的崔步,所以如果我們不需要這樣的一個動畫效果稳吮,可以使用 dontAnimate() 來禁用動畫效果。


有一些情況下井濒,crossFade() 方法并不能滿足我們的需求灶似。如果對加載的動畫有特殊的定制需要,可以使用更靈活的 animate() 方法來自己實現(xiàn)動畫瑞你。


可以看到酪惭,animate() 支持多種格式的動畫的配置,對于動畫的效果者甲,這里就不一一講解了春感。

4.6 支持 Gif & 視頻

Glide 的一個非常棒的功能,就是可以支持 Gif,并且使用起來和正常的想要加載一張網(wǎng)絡上的圖片鲫懒,并沒有什么區(qū)別嫩实。


上面的例子中,會在 mBgImageView 中顯示 Gif 圖的效果窥岩,并且自動播放甲献,并且可以在加載前為其設置一個占位圖,這些都和加載一個普通的圖片沒有什么區(qū)別颂翼。

但是有時候我們需要對加載的 Gif 圖做一個檢查晃洒,例如校驗它是否是一個 Gif ,如果不是朦乏,則認為是一次錯誤的加載球及。這個時候就可以使用 asGif() 來進行校驗,如果當前加載的圖片不是一個正確的 Gif 格式呻疹,則會去顯示 error() 配置的圖片吃引。


當然,有時候我們可能只是為了顯示一張圖片诲宇,可以強制顯示 Gif 圖片的第一幀际歼,使用 asBitmap() 方法標記即可。

只需要將 asGif() 替換成 asBitmap() 就餓可以了姑蓝,這里不再單獨提供示例了。

Glide 對 Gif 的支持之外吕粗,提示還對 Video 格式的文件也進行了支持纺荧。但是它和 Gif 顯示的效果不一樣的一點在于,它并不會去播放視頻文件颅筋,而只是將視頻文件的第一幀做為一個圖片去顯示出來宙暇。如果依然想要播放一段視頻文件,使用 Glide 不是一個好注意议泵,你應該使用 VideoView占贫。

其次 Glide 對視頻的支持,僅限于本地視頻先口,并無法對網(wǎng)絡視頻進行支持型奥。

4.7 加載監(jiān)聽

如果有對 Glide 加載的圖片的結(jié)果進行監(jiān)聽的,可以使用 listener() 方法設置一個監(jiān)聽器碉京,它接收一個 RequestListener 的接口


一般而言厢汹,如果我們需要監(jiān)聽圖片加載錯誤的原因,可以在 onException() 中做處理谐宙。

需要注意的是烫葬,這兩個方法的返回值,最好都是 false,因為如果返回 true 搭综,將表示你已經(jīng)處理了這次的事件垢箕,而 Glide 將不會再做額外的處理。例如兑巾,如果 onException() 返回了 true 的話条获,在圖片加載失敗之后,error() 中設置的圖片闪朱,并不會被顯示月匣,因為 Glide 認為開發(fā)者已經(jīng)在外部對這個錯誤進行了處理。

4.8 變換加載的圖片

對于使用 Glide 加載的圖片奋姿,如果想要在其顯示之前锄开,對其進行一些變換操作,例如称诗,改變顏色萍悴、虛化、圓角子類的寓免,都需要用到 transfrom() 方法癣诱,它主要用于支持在圖片顯示之前,自定義的變換效果袜香。

變換有兩個方法:

  • transfrom():它可以添加一個通用的變換效果撕予。
  • bitmapTransfrom():限制了變換的類型,只能設置 Bitmap 的變換蜈首。

變換這種操作实抡,其實定制性非常的強,展開講就比較復雜了欢策,大家只需要知道吆寨,Glide 是可以對加載的圖片在顯示之前進行一些預處理的操作的,在具體使用的時候再回頭來看相關資料即可踩寇。

這里推薦一個開源的庫啄清,來支持大多數(shù)變換的效果。

Github 地址:

https://github.com/wasabeef/glide-transformations

4.9 into() 其他實現(xiàn)

前面所有的例子中俺孙,into() 方法作為 Glide 加載圖片流程的最后一個環(huán)節(jié)辣卒,它不僅僅只能支持一個 ImageView。有時候我們還需要給 View 中設置一個背景的需要鼠冕,這個使用 Glide 也是可以辦到的添寺,但是就需要用到 into() 方法的其他重載方法了。


撇開 into(ImageView) 不說懈费,into(int,int) 實際上是一個指定尺寸的同步方法计露,可以在子線程中,通過它來得到一個 GlideDrawable 對象。


但是這并不是很常用的場景票罐,大部分我們還是使用泛型的方式來使用 Glide 的叉趣。


它的完整簽名可以看出,它實際上接收的是一個 Target 對象该押,而 Glide 同時也提供了非常多的 Target 的子類疗杉。


這些子類里面,有一些是不常用的蚕礼,例如 AppWidgetTarget 和 NotificationTarget 就是為了 AppWidget 和 Notification 中加載圖片準備的烟具。這里只介紹兩個比較常用的 Target :SimpleTarget 和 ViewTarget ,其實使用起來都是大同小異奠蹬。

如果我們不關心圖片加載的用途朝聋,只是單純的需要加載一個 Bitmap 或者 Drawable ,就可以使用 SimpleTarget 來處理囤躁。


SimpleTarget 可以接受一個 GlideDrawable 或者 Bitmap 的類型作為加載的類型冀痕。如果需要指定加載的圖片尺寸,還可以在構(gòu)造方法中指定狸演,如果不對其進行指定言蛇,則加載的是圖片的原尺寸。

再來看看 ViewTarget宵距, 從名稱上可以才出來腊尚,它實際上是想讓 Glide 加載一個圖片資源給某個 View 使用。它可以解決有時候我們顯示圖片的 View 并不是一個 ImageView 的問題满哪,也可能是一個 View 的背景跟伏。


ViewTarget 需要指定 View 的類型,以及加載的資源類型翩瓜,這里直接使用的 View 和 GlideDrawable ,然后將我們需要的使用圖片的目標 View 當構(gòu)造參數(shù)傳遞進去即可携龟,最終它它會一個內(nèi)部 view 變量去持有它兔跌,供之后使用。

在 onResourceReady() 這個回調(diào)方法中峡蟋,直接按我們的需要使用 GlideDrawable 和 View 即可坟桅。

如果是需要在非 ImageView 的其他 View 上使用圖片,推薦使用 ViewTarget 蕊蝗。它內(nèi)部是會去計算 View 的尺寸仅乓,來優(yōu)化緩存的圖片。和加載 ImageView 的效果是一樣的蓬戚,如果使用 SimpleTarget 就需要考慮到 View 的尺寸問題了夸楣。

在使用 Target 的時候,還有一點需要額外注意的。

前面也提到豫喧,Glide 此次加載的圖片生命周期石洗,會和 with() 傳遞進去的 Context 的生命周期進行綁定,所以使用 Target 加載圖片的時候紧显,就需要額外注意了讲衫,如果不是和頁面綁定的圖片資源,可以使用 ApplicationContext() 孵班,避免當前頁面被銷毀之后涉兽,加載的請求也被停止了。

五篙程、小結(jié)

本文最開始只是想要做一個適合初學者快速上手的 Glide 使用手冊枷畏,但是越寫越長,讀到這里相信你也能有所收獲房午,之后如果覺得有寫概念也需要初學者了解矿辽,會繼續(xù)補充。

公眾號二維碼.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末郭厌,一起剝皮案震驚了整個濱河市袋倔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌折柠,老刑警劉巖宾娜,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扇售,居然都是意外死亡前塔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門承冰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來华弓,“玉大人,你說我怎么就攤上這事困乒〖牌粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵娜搂,是天一觀的道長迁霎。 經(jīng)常有香客問我,道長百宇,這世上最難降的妖魔是什么考廉? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮携御,結(jié)果婚禮上昌粤,老公的妹妹穿的比我還像新娘既绕。我一直安慰自己,他們只是感情好婚苹,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布岸更。 她就那樣靜靜地躺著,像睡著了一般膊升。 火紅的嫁衣襯著肌膚如雪怎炊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天廓译,我揣著相機與錄音评肆,去河邊找鬼。 笑死非区,一個胖子當著我的面吹牛瓜挽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播征绸,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼久橙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了管怠?” 一聲冷哼從身側(cè)響起淆衷,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渤弛,沒想到半個月后祝拯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡她肯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年佳头,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晴氨。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡康嘉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出籽前,到底是詐尸還是另有隱情凄鼻,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布聚假,位于F島的核電站,受9級特大地震影響闰非,放射性物質(zhì)發(fā)生泄漏膘格。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一财松、第九天 我趴在偏房一處隱蔽的房頂上張望瘪贱。 院中可真熱鬧纱控,春花似錦、人聲如沸菜秦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽球昨。三九已至尔店,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間主慰,已是汗流浹背嚣州。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留共螺,地道東北人该肴。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像藐不,于是被迫代替她去往敵國和親匀哄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容