效果圖:
點此進入目錄:[干貨] 十天 教你從創(chuàng)意到上線APP
在圖片加載庫繁榮昌盛的今天,選擇一個適合自己使用的圖片加載庫已經(jīng)成為了每一個Android開發(fā)者的必經(jīng)之路」乱常現(xiàn)在市面上知名的圖片加載庫有UIL、Picasso虾攻、Volley ImageLoader裸扶、Fresco以及我們今天的主角Glide框都,它們各有千秋。但是Glide在眾多圖片加載庫中獨受青睞呵晨,我們來看下它的各種用法魏保。
一、Glide都有哪些優(yōu)點?
有Android開發(fā)經(jīng)驗的程序員可以跳過這一節(jié)摸屠,但是對于新手應(yīng)當(dāng)弄明白為什么你要使用Glide來代替你自己的實現(xiàn)谓罗,說的簡單點,還不是因為它有眾多優(yōu)點么季二,接下來帶大家一起去看看檩咱。
在Android中使用圖片的時候是相當(dāng)麻煩的,因為需要一個像素一個像素地加載這些圖片到內(nèi)存戒傻。一個中端手機(5百萬像素)所拍攝的一張照片有2592×1936這么大税手!這會占用大概19M內(nèi)存蜂筹!如果你再加上各種好壞不一的網(wǎng)絡(luò)下的圖片請求需纳,同時要處理緩存、圖片加載等問題艺挪,焦頭爛額不翩。如果你這時候使用了一個像Glide一樣經(jīng)過不斷優(yōu)化和嚴(yán)格測試的圖片處理庫兵扬,你會慶幸你節(jié)省了大量的時間,同時也避免了很多頭疼的問題口蝠。
所以器钟,我們?yōu)槭裁匆肎lide呢?就是為了避免我們處理紛繁復(fù)雜的圖片緩存妙蔗、加載等問題傲霸,從而剩下更多精力專注于業(yè)務(wù)邏輯的實現(xiàn)。
二眉反、Glide的簡單使用
1昙啄、添加Glide到依賴庫
(1)Gradle中添加
和大多數(shù)依賴庫一樣,在Gradle項目中只需要在build.gradle中添加一行:
compile 'com.github.bumptech.glide:glide:3.7.0'
(2)Maven
如果你用的是Maven構(gòu)建項目寸五,可以這么添加:
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<version>3.7.0</version>
<type>aar</type>
</dependency>
2梳凛、從 URL加載圖片
和Picasso類似的是,Glide同樣使用了一個流接口梳杏。用Glide完成一個完整的圖片加載功能請求韧拒,需要向其構(gòu)造器中至少傳入3個參數(shù),分別是:
-
with(Context context)
Context是許多Android API需要調(diào)用的十性, Glide也不例外叛溢。這里Glide非常方便,你可以任意傳遞一個Activity或者Fragment對象劲适,它都可以自動提取出上下文雇初。 -
load(String imageUrl)
這里傳入的是你要加載的圖片的URL,大多數(shù)情況下這個String類型的變量會鏈接到一個網(wǎng)絡(luò)圖片减响。 -
into(ImageView targetImageView)
將你所希望解析的圖片傳遞給所要顯示的ImageView靖诗。
下面我舉個栗子:
ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
String internetUrl = "http://image85.360doc.com/DownloadImg/2015/05/1722/53667314_4.jpg";
Glide
.with(context)
.load(internetUrl)
.into(targetImageView);
然后你就會發(fā)現(xiàn)在你想要的地方加載出如下圖片:
沒錯!加載圖片只需上面這幾行支示!如果這個URL鏈接的圖片的確存在刊橘,并且你的ImageView可見,你將會在1到2秒見到這張圖片被加載颂鸿。假如這張圖片不存在促绵,Glide會回調(diào)相應(yīng)的出錯接口。
3嘴纺、從Res資源中加載圖片
然后我們介紹從Android資源中加載败晴。不同于上面的String類型的網(wǎng)絡(luò)URL,這里是一個Int型的資源id栽渴。加載方法如下:
int resourceId = R.mipmap.ic_launcher;
Glide
.with(context)
.load(resourceId)
.into(imageViewResource);
你知道R.mipmap...這樣的資源定位方式嗎尖坤?這是Android的一個處理圖標(biāo)的新方法。雖然闲擦,你可以直接在ImageView的屬性里添加這一資源慢味。但是场梆,如果你使用Glide這種更高級的方式進行動態(tài)轉(zhuǎn)換,你的應(yīng)用可以做得非常有趣纯路。
4或油、從文件中加載圖片
從資源文件加載通常是固定的,當(dāng)你讓用戶任意選擇一張圖片來顯示的時候驰唬,這個文件的路徑并非是開發(fā)人員預(yù)先設(shè)定的顶岸,從圖片文件中加載對于實際應(yīng)用將會非常有用。需要傳遞的參數(shù)也僅僅是一個文件對象叫编,舉個栗子:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "WillFlow.jpg");
Glide
.with(context)
.load(file)
.into(imageViewFile);
5蜕琴、從Uri加載圖片
最后介紹從Uri中加載圖片,這里的請求跟上面的方法并無太大差異:
Uri uri = resourceIdToUri(context, R.mipmap.future_studio_launcher);
Glide
.with(context)
.load(uri)
.into(imageViewUri);
這個可以是任何Uri. 這里為了演示宵溅,我們只創(chuàng)建了一個指向桌面圖標(biāo)的Uri凌简。
如果你想要將資源id轉(zhuǎn)換為一個Uri,可以這樣:
public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FOREWARD_SLASH = "/";
private static Uri resourceIdToUri(Context context, int resourceId) {
return Uri.parse(ANDROID_RESOURCE + context.getPackageName() + FOREWARD_SLASH + resourceId);
}
當(dāng)然恃逻,Uri并不一定是從資源id中創(chuàng)建雏搂,它可以是任意Uri。
三寇损、Glide添加占位圖
1凸郑、默認(rèn)占位圖
空白的ImageView在任何UI中看起來都是丑陋的,Android中更是如此矛市。所以如果你在使用Glide從網(wǎng)絡(luò)上加載圖片芙沥,假如你網(wǎng)絡(luò)的環(huán)境不好,加載過程可能需要花費大量的時間浊吏。那么這時候就需要一個占位圖先顯示出圖片而昨,以此避免空白的顯示,直到正確的圖片加載完成并處理完畢后加載出來找田。
Glide的流接口讓這個工作變得很簡單歌憨!我們只要調(diào)用.placeHolder()并傳遞進去一個圖片資源,Glide會顯示那個占位圖墩衙,直到正確的圖片準(zhǔn)備完畢务嫡。
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504579473379&di=647a164ef14bf1cbf12917d3f53151ba&imgtype=0&src=http%3A%2F%2Fwww.taopic.com%2Fuploads%2Fallimg%2F140701%2F240398-140F10J52436.jpg")
.placeholder(R.mipmap.ic_launcher)
.into(imageViewPlaceholder);
毫無疑問,你不能設(shè)置一個網(wǎng)絡(luò)的Url當(dāng)作占位圖漆改。因為這樣的話占位圖也需要時間去加載心铃,這樣就使得占位圖失去了意義,所以App內(nèi)的資源和圖片是推薦使用的挫剑。同時去扣,由于Glide的load()可以接受各式的參數(shù),這些參數(shù)可能是不能加載的(無網(wǎng)絡(luò)連接暮顺、服務(wù)器掛掉厅篓、被刪除等)或者其他無法訪問的秀存,那么我們就需要用到出錯占位圖了捶码。
2羽氮、出錯占位圖
我們假設(shè)我們的App嘗試從網(wǎng)頁加載一張圖片但網(wǎng)頁不可訪問,Glide會去給我們進行出錯的回調(diào)惫恼,這時我們可以采取合適的行動(這個后面會說到)档押。這時一個出錯的占位圖可以用來表明圖片無法加載的情況,使得APP看起來更加友好祈纯。
跟預(yù)加載的占位圖一樣令宿,調(diào)用Glide的流接口即可:
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504579905069&di=5238a961892eef232fa51f717ded3946&imgtype=0&src=http%3A%2F%2Fimg1.xiazaizhijia.com%2Fwalls%2F20150120%2F1024x768_ad05a08bbd0b650.jpg")
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.future_studio_launcher)
.into(imageViewError);
上面的代碼中,如果從load()里傳入的圖片無法被加載腕窥,Glide會顯示R.mipmap.future_studio_launcher來代替粒没。再次強調(diào)一下,error()可以接受的只能是已經(jīng)被初始化的圖片資源或者指向圖片資源的id簇爆。
四癞松、Glide中的過渡動畫
1、使用動畫
無論你是否使用占位圖入蛆,圖片的改變對于UI來說是相當(dāng)大的一個動作响蓉。一個簡單的方法可以讓這個變化更平滑從而更讓人眼接受,這就是使用crossfade動畫哨毁。Glide支持標(biāo)準(zhǔn)的crossfade動畫枫甲,對于目前版本3.7.0是默認(rèn)可用的。如果你想要使用crossfade動畫扼褪,你只要在在構(gòu)造器里添加這樣一個調(diào)用:
Glide.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292512&di=067e20c865d5f97cf2a4558f318d1f8a&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F130131%2F240473-13013109324311.jpg")
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.future_studio_launcher)
.crossFade()
.into(imageViewFade);
如果你想要減慢(或加快)動畫想幻,crossFade()方法提供了另外一個特征:crossFade(int duration),我們可以傳入一個毫秒級的時間進去感受一下话浇,默認(rèn)的動畫時間是300毫秒举畸。
2、關(guān)閉動畫
如果你只是直接顯示圖片凳枝,而不需要crossfade效果抄沮,那就在Glide的請求構(gòu)造里調(diào)用.dontAnimate():
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292506&di=25693b1d27ac0c3fc6f36c037920d016&imgtype=0&src=http%3A%2F%2Fimg01.taopic.com%2F161009%2F240386-16100Z9320636.jpg")
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.future_studio_launcher)
.dontAnimate()
.into(imageViewFade);
有個重要的事情要提醒你,這些參數(shù)都是獨立的并且設(shè)置不依賴彼此岖瑰。例如叛买,你可以只設(shè)置.error()而不用調(diào)用.placeholder()。你可以設(shè)置crossFade()動畫而不用設(shè)置占位圖... 參數(shù)的任意結(jié)合都是可行的蹋订。
五率挣、Glide中圖片大小與縮放
1、設(shè)置大小
理想情況下服務(wù)器能夠返回給恰好所需分辨率的圖片露戒,這是在網(wǎng)絡(luò)帶寬椒功、內(nèi)存消耗和圖片質(zhì)量下的完美方案捶箱。跟Picasso比起來,Glide在內(nèi)存上占用更優(yōu)化动漾。Glide在緩存和內(nèi)存里自動限制圖片的大小去適配ImageView的尺寸丁屎。(Picasso也有同樣的能力,但需要調(diào)用fit()方法旱眯。)用Glide時晨川,如果圖片不需要自動適配ImageView,調(diào)用override(horizontalSize, verticalSize)删豺,它會在將圖片顯示在ImageView之前調(diào)整圖片的大小共虑。
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292505&di=4d945076bd552fa737195159cacb25cb&imgtype=0&src=http%3A%2F%2Fwww.bz55.com%2Fuploads%2Fallimg%2F150617%2F140-15061G13041.jpg")
.override(600, 200)
.into(imageViewResize);
這個設(shè)置可以用在沒有明確目標(biāo)但已知尺寸的視圖上。例如:如果App想要預(yù)先緩存在Splash屏幕上呀页,還沒法測量出ImageVIews具體寬高妈拌,但已經(jīng)知道圖片應(yīng)當(dāng)為多大,這時使用override可以提供一個指定的大小的圖片蓬蝶。
2尘分、設(shè)置縮放
對于任何圖像的任何處理來說,調(diào)整圖像的大小可能會扭曲長寬比丑化圖片的顯示疾党。在大多數(shù)情況下音诫,我們希望防止這種事情發(fā)生。Glide提供了變換去處理圖片顯示雪位,通過設(shè)置centerCrop 和 fitCenter可以得到兩個不同的效果(這類似于ImageView里面的用法)竭钝。
(1)CenterCrop
CenterCrop()會縮放圖片讓圖片充滿整個ImageView的邊框,然后裁掉超出的部分雹洗,ImageVIew會被完全填充滿香罐,但是圖片可能不能完全顯示出。
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292492&di=8864ca8d00cee6849b628404f89ae7e1&imgtype=0&src=http%3A%2F%2Fbbs.kaitao.cn%2Fshangchuan%2F2013-08-27%2F20130827101902.jpg")
.override(600, 200)
.centerCrop()
.into(imageViewResizeCenterCrop);
(2)FitCenter
FitCenter()會縮放圖片讓兩邊都相等或小于ImageView的所需求的邊框时肿。圖片會被完整顯示庇茫,可能不能完全填充整個ImageView。
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292492&di=8864ca8d00cee6849b628404f89ae7e1&imgtype=0&src=http%3A%2F%2Fbbs.kaitao.cn%2Fshangchuan%2F2013-08-27%2F20130827101902.jpg")
.override(600, 200)
.fitCenter()
.into(imageViewResizeFitCenter);
我們會之后的文章中介紹除了centerCrop() 和 fitCenter()以外的自定義變換方法螃成,這里首先給出不同尺寸的圖片在運用不同屬性時的效果圖:
六旦签、Glide中的緩存
當(dāng)你不斷向上向下滑動多次后,你會發(fā)現(xiàn)圖片會比之前加載地更快寸宏。在新手機上可能需要稍微多等一會宁炫。你可以很容易想到,這些圖片由于被緩存到磁盤上氮凝,用的時候不必再從網(wǎng)絡(luò)獲取羔巢。Glide的緩存實現(xiàn)是基于Picasso的一個方法,讓你可以更簡單地使用。具體可以緩存的大小取決于設(shè)備磁盤的大小竿秆。當(dāng)加載一張圖片時启摄,Glide使用這些資源:內(nèi)存、磁盤和網(wǎng)絡(luò)(根據(jù)由快到慢)幽钢。第二次加載的時候歉备,你啥都不用做,一旦Glide智能地創(chuàng)建了合適大小的圖片緩存搅吁,將為你分擔(dān)了所有復(fù)雜工作威创。
1落午、內(nèi)存緩存
如果你在前面用Glide用的很溜谎懦,你可能注意到你并不需要額外自己激活緩存。Glide本身自帶緩存溃斋。然而界拦,如果你的圖片變化的非常快梗劫,你需要避免一些緩存享甸。
從網(wǎng)絡(luò)加載一個圖片到ImageView:
Glide .with( context )
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292492&di=8864ca8d00cee6849b628404f89ae7e1&imgtype=0&src=http%3A%2F%2Fbbs.kaitao.cn%2Fshangchuan%2F2013-08-27%2F20130827101902.jpg")
.skipMemoryCache( true )
.into( imageViewInternet );
我們調(diào)用了.skipMemoryCache(true)
去告訴Glide跳過內(nèi)存緩存,這意味著Glide不會把這個圖片緩存到內(nèi)存里梳侨。重要是蛉威,這個只影響內(nèi)存緩存!Glide為了避免以后的網(wǎng)絡(luò)請求走哺,仍然會緩存到磁盤蚯嫌。另外,由于Glide默認(rèn)會將所有的圖片資源緩存到內(nèi)存中丙躏,因此沒有必要手動調(diào)用.skipMemoryCache(false)
了择示。
注意:如果你要對同一個URL做一個初始化的請求,第一次沒使用
.skipMemoryCache(true)
晒旅,然后第二次使用了栅盲,將會獲取緩存在內(nèi)存中的資源。當(dāng)你調(diào)整緩存行為的時候废恋,確保請求的都是指向同一個資源谈秫。
2、磁盤緩存
如上面所講到的鱼鼓,即使你關(guān)閉了內(nèi)存緩存拟烫,所請求的圖片仍然會被保存在設(shè)備的磁盤存儲上。如果你有一張不段變化的圖片蚓哩,但是都是用的同一個URL构灸,你可能需要禁止磁盤緩存了。
你可以用.diskCacheStrategy()
方法改變Glide的磁盤緩存行為,但不同于.skipMemoryCache()
方法喜颁,它將需要從枚舉型變量中選擇一個稠氮,而不是一個簡單的boolean。如果你想要禁止請求的磁盤緩存半开,使用枚舉型變量DiskCacheStrategy.NONE作為參數(shù)隔披。
Glide .with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292492&di=8864ca8d00cee6849b628404f89ae7e1&imgtype=0&src=http%3A%2F%2Fbbs.kaitao.cn%2Fshangchuan%2F2013-08-27%2F20130827101902.jpg")
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageViewInternet);
上面代碼里的圖片根本不會被保存在磁盤上,然而默認(rèn)情況下它仍然使用內(nèi)存緩存寂拆!為了同時禁止掉兩個緩存奢米,結(jié)合以下方法:
Glide
.with(context)
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504580292492&di=8864ca8d00cee6849b628404f89ae7e1&imgtype=0&src=http%3A%2F%2Fbbs.kaitao.cn%2Fshangchuan%2F2013-08-27%2F20130827101902.jpg")
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(imageViewInternet);
3、自定義磁盤緩存行為
正如我們之前提到的纠永,Glide有很多磁盤緩存的策略鬓长。在我們展示這些選項前,你可能意識到Glide的磁盤緩存是相當(dāng)復(fù)雜的尝江。Picasso只緩存全尺寸圖片涉波;Glide會緩存原始尺寸的圖片和額外的小版本圖片。例如炭序,如果你請求一個1000x1000像素的圖片啤覆,你的ImageView是500x500像素,Glide會保存兩個版本的圖片到緩存里惭聂。
現(xiàn)在窗声,你應(yīng)該明白.diskCacheStrategy()中枚舉參數(shù)的意義了:
- DiskCacheStrategy.NONE 啥也不緩存
- DiskCacheStrategy.SOURCE 只緩存全尺寸圖
- DiskCacheStrategy.RESULT 只緩存最終降低分辨后用到的圖片
- DiskCacheStrategy.ALL 緩存所有類型的圖片(默認(rèn)行為)
更多的關(guān)于Glide和Picasso的對比,你可以參考這里:
聯(lián)系方式: