glide入門(轉(zhuǎn)自郭霖大神的微信公眾號)

最近在做群聊功能,使用了環(huán)信的SDK,在環(huán)信demo中無意之中看到了glide框架,簡單了解后,發(fā)現(xiàn)這個框架很強(強到?jīng)]朋友),不光可以加載本地,網(wǎng)絡(luò)靜態(tài)圖片,還可以加載gif動態(tài)圖片.今天就轉(zhuǎn)載一篇郭霖(第一行android代碼的作者)大神介紹的glide入門文章.

現(xiàn)在Android上的圖片加載框架非常成熟,從最早的老牌圖片加載框架UniversalImageLoader惩猫,到后來Google推出的Volley,再到后來的新興軍Glide和Picasso轧房,當然還有Facebook的Fresco拌阴。每一個都非常穩(wěn)定,功能也都十分強大奶镶。但是它們的使用場景基本都是重合的迟赃,也就是說我們基本只需要選擇其中一個來進行學習和使用就足夠了,每一個框架都嘗試去掌握的話則有些浪費時間厂镇。

在這幾個框架當中纤壁,我對Volley和Glide研究得比較深入,對UniversalImageLoader捺信、Picasso和Fresco都只是有一些基本的了解酌媒。從易用性上來講,Glide和Picasso應(yīng)該都是完勝其他框架的迄靠,這兩個框架都實在是太簡單好用了秒咨,大多數(shù)情況下加載圖片都是一行代碼就能解決的,而UniversalImageLoader和Fresco則在這方面略遜一些掌挚。

總之雨席,沒有最好的框架,只有最適合自己的框架吠式。經(jīng)過多方面對比之后陡厘,我還是決定選擇了Glide來進行研究,并且這也是Google官方推薦的圖片加載框架奇徒。

說實話雏亚,關(guān)于Glide的文章我已經(jīng)籌備了好久,去年這個時候本來就打算要寫了摩钙,但是一直都沒有動筆罢低。因為去年我的大部分時間都放在了寫《第二行代碼》上面,只能用碎片時間來寫寫博客,但是Glide的難度遠超出了我用碎片時間所能掌握的難度网持。當然宜岛,這里我說的是對它的源碼進行解析的難度,不是使用上的難度功舀,Glide的用法是很簡單的萍倡。所以,我覺得去年我寫不好Glide這個題材的文章辟汰,也就一直拖到了今年列敲。

而現(xiàn)在,我花費了大量的精力去研究Glide的源碼和各種用法帖汞,相信現(xiàn)在已經(jīng)可以將它非常好地掌握了戴而,因此我準備將我掌握的這些知識整理成一個新的系列,幫忙大家更好地學習Glide翩蘸。這個Glide系列大概會有8篇左右文章所意,預(yù)計花半年時間寫完,將會包括Glide的基本用法催首、源碼解析扶踊、高級用法、功能擴展等內(nèi)容郎任,可能會是目前互聯(lián)網(wǎng)上最詳盡的Glide教程秧耗。

那么本篇文章是這個系列的第一篇文章,我們先來了解一下Glide的基本用法吧涝滴。

開始

Glide是一款由Bump Technologies開發(fā)的圖片加載框架绣版,使得我們可以在Android平臺上以極度簡單的方式加載和展示圖片。

目前歼疮,Glide最新的穩(wěn)定版本是3.7.0杂抽,雖然3.8.0已經(jīng)推出預(yù)覽版了,但是暫時問題還比較多韩脏。因此缩麸,我們這個系列的博客都會使用Glide 3.7.0版本來進行講解,這個版本的Glide相當成熟和穩(wěn)定赡矢。

要想使用Glide杭朱,首先需要將這個庫引入到我們的項目當中。新建一個GlideTest項目吹散,然后在app/build.gradle文件當中添加如下依賴:

dependencies { ? ?compile'com.github.bumptech.glide:glide:3.7.0'}

另外弧械,Glide中需要用到網(wǎng)絡(luò)功能,因此你還得在AndroidManifest.xml中聲明一下網(wǎng)絡(luò)權(quán)限才行:

<uses-permission android:name="android.permission.INTERNET"/>

就是這么簡單空民,然后我們就可以自由地使用Glide中的任意功能了刃唐。

加載圖片

現(xiàn)在我們就來嘗試一下如何使用Glide來加載圖片吧羞迷。比如這是必應(yīng)上一張首頁美圖的地址:

http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg

然后我們想要在程序當中去加載這張圖片。

那么首先打開項目的布局文件画饥,在布局當中加入一個Button和一個ImageView衔瓮,如下所示

為了讓用戶點擊Button的時候能夠?qū)偛诺膱D片顯示在ImageView上,我們需要修改MainActivity中的代碼抖甘,如下所示:

publicclassMainActivityextendsAppCompatActivity{

?????? ImageViewimageView;

@OverrideprotectedvoidonCreate(BundlesavedInstanceState) {

??????? super.onCreate(savedInstanceState);

??????? setContentView(R.layout.activity_main);

??????? imageView=(ImageView) findViewById(R.id.image); ?}

???????? public void loadImage(Viewview) {

???????????????????? Stringurl="http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg";

???????????????????? Glide.with(this).load(url).into(imageView);

? ? ? ?? }

}

沒錯热鞍,就是這么簡單。現(xiàn)在我們來運行一下程序衔彻,效果如下圖所示:

可以看到薇宠,一張網(wǎng)絡(luò)上的圖片已經(jīng)被成功下載,并且展示到ImageView上了米奸。

而我們到底做了什么昼接?實際上核心的代碼就只有這一行而已:

Glide.with(this).load(url).into(imageView);

千萬不要小看這一行代碼,實際上僅僅就這一行代碼悴晰,你已經(jīng)可以做非常非常多的事情了,包括加載網(wǎng)絡(luò)上的圖片逐工、加載手機本地的圖片铡溪、加載應(yīng)用資源中的圖片等等。

下面我們就來詳細解析一下這行代碼泪喊。

首先棕硫,調(diào)用Glide.with()方法用于創(chuàng)建一個加載圖片的實例。with()方法可以接收Context袒啼、Activity或者Fragment類型的參數(shù)哈扮。也就是說我們選擇的范圍非常廣,不管是在Activity還是Fragment中調(diào)用with()方法蚓再,都可以直接傳this滑肉。那如果調(diào)用的地方既不在Activity中也不在Fragment中呢?也沒關(guān)系摘仅,我們可以獲取當前應(yīng)用程序的ApplicationContext靶庙,傳入到with()方法當中。注意with()方法中傳入的實例會決定Glide加載圖片的生命周期娃属,如果傳入的是Activity或者Fragment的實例六荒,那么當這個Activity或Fragment被銷毀的時候,圖片加載也會停止矾端。如果傳入的是ApplicationContext掏击,那么只有當應(yīng)用程序被殺掉的時候,圖片加載才會停止秩铆。

接下來看一下load()方法砚亭,這個方法用于指定待加載的圖片資源。Glide支持加載各種各樣的圖片資源,包括網(wǎng)絡(luò)圖片钠惩、本地圖片柒凉、應(yīng)用資源靴庆、二進制流悬秉、Uri對象等等颖杏。因此load()方法也有很多個方法重載户矢,除了我們剛才使用的加載一個字符串網(wǎng)址之外圃郊,你還可以這樣使用load()方法:

//加載本地圖片

Filefile=getImagePath();

Glide.with(this).load(file).into(imageView);

//加載應(yīng)用資源

intresource=R.drawable.image;

Glide.with(this).load(resource).into(imageView);

//加載二進制流

byte[] image=getImageBytes();

Glide.with(this).load(image).into(imageView);

//加載Uri對象

UriimageUri=getImageUri();

Glide.with(this).load(imageUri).into(imageView);

最后看一下into()方法剧腻,這個方法就很簡單了曹动,我們希望讓圖片顯示在哪個ImageView上谚中,把這個ImageView的實例傳進去就可以了沐寺。當然林艘,into()方法不僅僅是只能接收ImageView類型的參數(shù),還支持很多更豐富的用法混坞,不過那個屬于高級技巧狐援,我們會在后面的文章當中學習。

那么回顧一下Glide最基本的使用方式究孕,其實就是關(guān)鍵的三步走:先with()啥酱,再load(),最后into()厨诸。熟記這三步镶殷,你就已經(jīng)入門Glide了。

占位圖

現(xiàn)在我們來學一些Glide的擴展內(nèi)容微酬。其實剛才所學的三步走就是Glide最核心的東西绘趋,而我們后面所要學習的所有東西都是在這個三步走的基礎(chǔ)上不斷進行擴展而已。

觀察剛才加載網(wǎng)絡(luò)圖片的效果颗管,你會發(fā)現(xiàn)陷遮,點擊了Load Image按鈕之后,要稍微等一會圖片才會顯示出來忙上。這其實很容易理解拷呆,因為從網(wǎng)絡(luò)上下載圖片本來就是需要時間的。那么我們有沒有辦法再優(yōu)化一下用戶體驗?zāi)匾咧啵慨斎豢梢圆绺珿lide提供了各種各樣非常豐富的API支持,其中就包括了占位圖功能梗逮。

顧名思義项秉,占位圖就是指在圖片的加載過程中,我們先顯示一張臨時的圖片慷彤,等圖片加載出來了再替換成要加載的圖片娄蔼。

下面我們就來學習一下Glide占位圖功能的使用方法怖喻,首先我事先準備好了一張loading.jpg圖片,用來作為占位圖顯示岁诉。然后修改Glide加載部分的代碼锚沸,如下所示:

Glide.with(this).load(url).placeholder(R.drawable.loading).into(imageView);

沒錯,就是這么簡單涕癣。我們只是在剛才的三步走之間插入了一個placeholder()方法哗蜈,然后將占位圖片的資源id傳入到這個方法中即可。另外坠韩,這個占位圖的用法其實也演示了Glide當中絕大多數(shù)API的用法距潘,其實就是在load()和into()方法之間串接任意想添加的功能就可以了。

不過如果你現(xiàn)在重新運行一下代碼并點擊Load Image只搁,很可能是根本看不到占位圖效果的音比。因為Glide有非常強大的緩存機制,我們剛才加載那張必應(yīng)美圖的時候Glide自動就已經(jīng)將它緩存下來了氢惋,下次加載的時候?qū)苯訌木彺嬷凶x取洞翩,不會再去網(wǎng)絡(luò)下載了,因而加載的速度非逞嫱快菱农,所以占位圖可能根本來不及顯示。

因此這里我們還需要稍微做一點修改柿估,來讓占位圖能有機會顯示出來,修改代碼如下所示:

Glide.with(this).load(url).placeholder(R.drawable.loading).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

可以看到陷猫,這里串接了一個diskCacheStrategy()方法秫舌,并傳入DiskCacheStrategy.NONE參數(shù),這樣就可以禁用掉Glide的緩存功能绣檬。

關(guān)于Glide緩存方面的內(nèi)容我們將會在后面的文章進行詳細的講解足陨,這里只是為了測試占位圖功能而加的一個額外配置,暫時你只需要知道禁用緩存必須這么寫就可以了娇未。

現(xiàn)在重新運行一下代碼墨缘,效果如下圖所示:


可以看到,當點擊Load Image按鈕之后會立即顯示一張占位圖零抬,然后等真正的圖片加載完成之后會將占位圖替換掉镊讼。

當然,這只是占位圖的一種平夜,除了這種加載占位圖之外蝶棋,還有一種異常占位圖。異常占位圖就是指忽妒,如果因為某些異常情況導(dǎo)致圖片加載失敗玩裙,比如說手機網(wǎng)絡(luò)信號不好兼贸,這個時候就顯示這張異常占位圖。

異常占位圖的用法相信你已經(jīng)可以猜到了吃溅,首先準備一張error.jpg圖片溶诞,然后修改Glide加載部分的代碼,如下所示:

Glide.with(this).load(url).placeholder(R.drawable.loading).error(R.drawable.error).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

很簡單决侈,這里又串接了一個error()方法就可以指定異常占位圖了螺垢。

現(xiàn)在你可以將圖片的url地址修改成一個不存在的圖片地址,或者干脆直接將手機的網(wǎng)絡(luò)給關(guān)了颜及,然后重新運行程序甩苛,效果如下圖所示:


這樣我們就把Glide提供的占位圖功能都掌握了。

指定圖片格式

我們還需要再了解一下Glide另外一個強大的功能俏站,那就是Glide是支持加載GIF圖片的讯蒲。這一點確實非常牛逼,因為相比之下Jake Warton曾經(jīng)明確表示過肄扎,Picasso是不會支持加載GIF圖片的墨林。

而使用Glide加載GIF圖并不需要編寫什么額外的代碼,Glide內(nèi)部會自動判斷圖片格式犯祠。比如這是一張GIF圖片的URL地址:

http://p1.pstatp.com/large/166200019850062839d3

我們只需要將剛才那段加載圖片代碼中的URL地址替換成上面的地址就可以了旭等,現(xiàn)在重新運行一下代碼,效果如下圖所示:


也就是說衡载,不管我們傳入的是一張普通圖片搔耕,還是一張GIF圖片,Glide都會自動進行判斷痰娱,并且可以正確地把它解析并展示出來弃榨。

但是如果我想指定圖片的格式該怎么辦呢?就比如說梨睁,我希望加載的這張圖必須是一張靜態(tài)圖片鲸睛,我不需要Glide自動幫我判斷它到底是靜圖還是GIF圖。

想實現(xiàn)這個功能仍然非常簡單坡贺,我們只需要再串接一個新的方法就可以了官辈,如下所示:

Glide.with(this).load(url).asBitmap().placeholder(R.drawable.loading).error(R.drawable.error).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

可以看到,這里在load()方法的后面加入了一個asBitmap()方法遍坟,這個方法的意思就是說這里只允許加載靜態(tài)圖片拳亿,不需要Glide去幫我們自動進行圖片格式的判斷了。

現(xiàn)在重新運行一下程序政鼠,效果如下圖所示:


由于調(diào)用了asBitmap()方法风瘦,現(xiàn)在GIF圖就無法正常播放了,而是會在界面上顯示第一幀的圖片公般。

那么類似地万搔,既然我們能強制指定加載靜態(tài)圖片胡桨,就也能強制指定加載動態(tài)圖片。比如說我們想要實現(xiàn)必須加載動態(tài)圖片的功能瞬雹,就可以這樣寫:

Glide.with(this).load(url).asGif().placeholder(R.drawable.loading).error(R.drawable.error).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

這里調(diào)用了asGif()方法替代了asBitmap()方法昧谊,很好理解,相信不用我多做什么解釋了酗捌。

那么既然指定了只允許加載動態(tài)圖片呢诬,如果我們傳入了一張靜態(tài)圖片的URL地址又會怎么樣呢?試一下就知道了胖缤,將圖片的URL地址改成剛才的必應(yīng)美圖尚镰,然后重新運行代碼,效果如下圖所示哪廓。

動圖


沒錯狗唉,如果指定了只能加載動態(tài)圖片,而傳入的圖片卻是一張靜圖的話涡真,那么結(jié)果自然就只有加載失敗嘍分俯。

指定圖片大小

實際上,使用Glide在絕大多數(shù)情況下我們都是不需要指定圖片大小的哆料。

在學習本節(jié)內(nèi)容之前缸剪,你可能還需要先了解一個概念,就是我們平時在加載圖片的時候很容易會造成內(nèi)存浪費东亦。什么叫內(nèi)存浪費呢杏节?比如說一張圖片的尺寸是1000*1000像素,但是我們界面上的ImageView可能只有200*200像素典阵,這個時候如果你不對圖片進行任何壓縮就直接讀取到內(nèi)存中拢锹,這就屬于內(nèi)存浪費了,因為程序中根本就用不到這么高像素的圖片萄喳。

而使用Glide,我們就完全不用擔心圖片內(nèi)存浪費蹋半,甚至是內(nèi)存溢出的問題他巨。因為Glide從來都不會直接將圖片的完整尺寸全部加載到內(nèi)存中,而是用多少加載多少减江。Glide會自動判斷ImageView的大小染突,然后只將這么大的圖片像素加載到內(nèi)存當中,幫助我們節(jié)省內(nèi)存開支辈灼。

也正是因為Glide是如此的智能份企,所以剛才在開始的時候我就說了,在絕大多數(shù)情況下我們都是不需要指定圖片大小的巡莹,因為Glide會自動根據(jù)ImageView的大小來決定圖片的大小司志。

不過甜紫,如果你真的有這樣的需求,必須給圖片指定一個固定的大小骂远,Glide仍然是支持這個功能的囚霸。修改Glide加載部分的代碼,如下所示:

Glide.with(this).load(url).placeholder(R.drawable.loading).error(R.drawable.error).diskCacheStrategy(DiskCacheStrategy.NONE).override(100,100).into(imageView);

仍然非常簡單激才,這里使用override()方法指定了一個圖片的尺寸拓型,也就是說,Glide現(xiàn)在只會將圖片加載成100*100像素的尺寸瘸恼,而不會管你的ImageView的大小是多少了劣挫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市东帅,隨后出現(xiàn)的幾起案子压固,更是在濱河造成了極大的恐慌,老刑警劉巖冰啃,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邓夕,死亡現(xiàn)場離奇詭異,居然都是意外死亡阎毅,警方通過查閱死者的電腦和手機焚刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扇调,“玉大人矿咕,你說我怎么就攤上這事±桥ィ” “怎么了碳柱?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熬芜。 經(jīng)常有香客問我莲镣,道長,這世上最難降的妖魔是什么涎拉? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任瑞侮,我火速辦了婚禮,結(jié)果婚禮上鼓拧,老公的妹妹穿的比我還像新娘半火。我一直安慰自己,他們只是感情好季俩,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布钮糖。 她就那樣靜靜地躺著,像睡著了一般酌住。 火紅的嫁衣襯著肌膚如雪店归。 梳的紋絲不亂的頭發(fā)上阎抒,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音娱节,去河邊找鬼挠蛉。 笑死,一個胖子當著我的面吹牛肄满,可吹牛的內(nèi)容都是我干的谴古。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼稠歉,長吁一口氣:“原來是場噩夢啊……” “哼掰担!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怒炸,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤带饱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后阅羹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勺疼,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年捏鱼,在試婚紗的時候發(fā)現(xiàn)自己被綠了执庐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡导梆,死狀恐怖轨淌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情看尼,我是刑警寧澤递鹉,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站藏斩,受9級特大地震影響躏结,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狰域,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一窜觉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧北专,春花似錦、人聲如沸旬陡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽描孟。三九已至驶睦,卻和暖如春砰左,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背场航。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工缠导, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人溉痢。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓僻造,卻偏偏與公主長得像,于是被迫代替她去往敵國和親孩饼。 傳聞我的和親對象是個殘疾皇子髓削,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

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