直接用代碼方式說下:
Glide.with(act).load(strImage)
/**
* Glide加載時我們可以通過fitCenter()和
* centerCrop方法直接在代碼中對ImageView進行設定
* fitCenter() 是裁剪技術,即縮放圖像讓圖像都測量
* 出來等于或小于 ImageView 的邊界範圍。該圖像
* 将會完全顯示,但可能不會填滿整個 ImageView
* CenterCrop()是一個裁剪技術,即縮放圖像讓它填
* 充到 ImageView 界限内并且裁剪額外的部
* 分。ImageView 可能會完全填充,但圖像可能不會
* 完整顯示。
*/
.centerCrop()
/**
* Glide有淡入淡出的效果,因為它有
crossFade()
crossFade(intanimationId, int duration)
crossfade(intduration)動畫預設的持續
時間是 300毫秒
*/
.crossFade()
/**
* 加載小圖,圓圖的1/8
*/
.thumbnail( /)
/**
* DiskCacheStrategy.NONE(不做任何磁盤緩存)
DiskCacheStrategy.RESULT(緩存轉換後的資源)
DiskCacheStrategy.SOURCE(緩存源資源)
*/
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
/**
* 如果圖檔不會自動适配到 ImageView,調用
* override(horizontalSize, verticalSize)
* 這将在圖檔顯示到 ImageView之前重新改變圖檔大小
*/
.override(, )
//占位圖
.placeholder(R.mipmap.ic_headimg)
//加載錯誤時顯示的圖檔
.error(R.mipmap.ic_headimg)
/**
* 如果你想直接顯示圖檔而沒有任何淡入淡出效果,
* 在 Glide 的建造者中調用 .dontAnimate()
*/
.dontAnimate()
.into(my_avatar_img);
另外Glide還有gif檢查功能:Gif 檢查
一個潛在的問題是,如果提供的來源不是一個 Gif,可能隻是一個正常圖檔,這就沒有辦法顯示這個問題。Glide 接受 Gif 或者圖檔作為 load() 參數。如果你期望這個 URL 是一個 Gif,Glide 不會自動檢查是否是 Gif。是以他們引入了一個額外的防區強制 Glide變成一個 Gif asGif():
Glide
.with( context )
.load( gifUrl )
.placeholder( R.drawable.cupcake )
.error( R.drawable.full_cake )
.into( imageViewGif );
這樣做的的好處是,.error() 回調被調用并且錯誤占位符被顯示,即使 gifUrl 是一個完美的圖檔(但不是一個 Gif)。
Gif 轉為 Bitmap
如果你的 App 顯示一個位置的網絡 URL 清單,它可能遇到正常的圖檔或者 Gif。在某些情況下,你可能對不想系那是整個 Gif。如果你僅僅想要顯示 Gif 的第一幀,你可以調用 asBitmap() 去保證其作為一個正常的圖檔顯示,即使這個 URL 是一個 Gif。
Glide
.with( context )
.load( gifUrl )
.asBitmap()
.into( imageViewGifAsBitmap );
顯示本地視訊
現在來談談視訊。Glide 還能顯示視訊!隻要他們是存儲在手機上的。讓我們假設你通過讓使用者選擇一個視訊後得到了一個檔案路徑:
String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
Glide
.with( context )
.load( Uri.fromFile( new File( filePath ) ) )
.into( imageViewGifAsBitmap );
這裡需要注意的是,這僅僅對于本地視訊起作用。如果沒有存儲在該裝置上的視訊(如一個網絡 URL 的視訊),它是不工作的!
使用緩存政策
Glide 提供了方法去适配記憶體和磁盤緩存行為。讓我們先看看記憶體緩存。
記憶體緩存
Glide
.with( context )
.load( eatFoodyImages[] )
.skipMemoryCache( true )
.into( imageViewInternet );
我們調用了 .skipMemoryCache(true) 去明确告訴 Glide 跳過記憶體緩存。這意味着 Glide 将不會把這張圖檔放到記憶體緩存中去。這裡需要明白的是,這隻是會影響記憶體緩存!Glide 将會仍然利用磁盤緩存來避免重複的網絡請求。這也容易知道 Glide 将會預設将所有的圖檔資源放到記憶體緩存中去。因為,指明調用 .skipMemoryCache(false) 是沒有必要的。
提示:注意一個事實,對于相同的 URL ,如果你的初始請求沒調用 .skipMemoryCache(true) 方法,你後來又調用了 .skipMemoryCache(true) 這個方法,這個資源将會在記憶體中擷取緩存。當你想要去調整緩存行為時,確定對同一個資源調用的一緻性。
跳過磁盤緩存
你可以用 .diskCacheStrategy() 方法為 Glide 改變磁盤緩存的行為。不同的于 .skipMemoryCache() 方法,它需要一個枚舉而不是一個簡答的布爾值。如果你想要為一個請求禁用磁盤緩存。使用枚舉 DiskCacheStrategy.NONE 作為參數。
Glide
.with( context )
.load( eatFoodyImages[] )
.diskCacheStrategy( DiskCacheStrategy.NONE )
.into( imageViewInternet );
圖檔在這段代碼片段中将不會被儲存在磁盤緩存中。然而,預設的它将仍然使用記憶體緩存!為了把這裡兩者都禁用掉,兩個方法一起調用:
Glide
.with( context )
.load( eatFoodyImages[] )
.diskCacheStrategy( DiskCacheStrategy.NONE )
.skipMemoryCache( true )
.into( imageViewInternet );
自定義磁盤緩存行為
對于 .diskCacheStrategy() 方法來說不同的枚舉參數的意義:
DiskCacheStrategy.NONE 什麼都不緩存,就像剛讨論的那樣
DiskCacheStrategy.SOURCE 僅僅隻緩存原來的全分辨率的圖像。在我們上面的例子中,将會隻有一個 x1000 像素的圖檔
DiskCacheStrategy.RESULT 僅僅緩存最終的圖像,即,降低分辨率後的(或者是轉換後的)
DiskCacheStrategy.ALL 緩存所有版本的圖像(預設行為)
作為最後一個例子,如果你有一張圖檔,你知道你将會經常操作處理,并做了一堆不同的版本,對其有意義的僅僅是緩存原始分辨率圖檔。是以,我們用 DiskCacheStrategy.SOURCE 去告訴 Glide 僅僅儲存原始圖檔:
Glide
.with( context )
.load( eatFoodyImages[] )
.diskCacheStrategy( DiskCacheStrategy.SOURCE )
.into( imageViewFile );
圖檔請求的優先級
了解 Priority (優先級)枚舉
這個枚舉給了四個不同的選項,下面是按照遞增priority(優先級)的清單:
Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE
在我們開始例子前,你應該知道的是:優先級并不是完全嚴格遵守的。Glide 将會用他們作為一個準則,并盡可能的處理這些請求,但是它不能保證所有的圖檔都會按照所要求的順序加載。
然而,如果你有的使用場景是确定一些圖檔是重要的,充分利用它!
讓我們開始回到開始時的例子吧。你正在實作一個資訊詳情頁面,有一個英雄圖檔在頂部,和較小的圖檔在底部。對于最好的使用者體驗來說,英雄圖檔首先需要被加載。是以,我們用 Priority.HIGH 來處理它。理論上說,這應該夠了,但是為了讓這個執行個體增加點趣味,我們也将底層圖像配置設定給低優先級,用 .priority(Priority.LOW) 調用:
private void loadImageWithHighPriority() {
Glide
.with( context )
.load( UsageExampleListViewAdapter.eatFoodyImages[] )
.priority( Priority.HIGH )
.into( imageViewHero );
}
private void loadImagesWithLowPriority() {
Glide
.with( context )
.load( UsageExampleListViewAdapter.eatFoodyImages[] )
.priority( Priority.LOW )
.into( imageViewLowPrioLeft );
Glide
.with( context )
.load( UsageExampleListViewAdapter.eatFoodyImages[] )
.priority( Priority.LOW )
.into( imageViewLowPrioRight );
}
如果你運作這個執行個體,你會看到,在幾乎所有的情況下,英雄圖檔将會首先顯示出來。盡管是更大的圖像(因為需要更多的處理時間)。
簡單的縮略圖
Glide 的 .thumbnail() 方法讓這一切成為可能。 在這樣的情況下,這個參數是一個 float 作為其大小的倍數。
Glide
.with( context )
.load( UsageExampleGifAndVideos.gifUrl )
.thumbnail( f )
.into( imageView2 );
例如, 你傳了一個 f 作為參數,Glide 将會顯示原始圖像的%的大小。如果原始圖像有 x1000 像素,那麼縮略圖将會有 x100 像素。因為這個圖像将會明顯比 ImageView 小很多,你需要確定它的 ScaleType 的設定是正确的。
Glide 中的回調:Targets
我們假定 ImageView 不再是圖像的最後一步。我們隻要 Bitmap 本身。Glide 提供了一個用 Targets 的簡單的方式去接受圖檔資源的 Bitmap。Targets 是沒有任何别的回調,它在 Glide 做完所有的加載和處理之後傳回結果。Glide 提供了各種的 targets 并且每個都有其明确的目的。我們将在接下來的幾節中通過使用它們。讓我們從 SimpleTarget 開始。
SimpleTarget
private SimpleTarget target = new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// do something with the bitmap
// for demonstration purposes, let's just set it to an ImageView
imageView1.setImageBitmap( bitmap );
}
};
private void loadImageSimpleTarget() {
Glide
.with( context ) // could be an issue!
.load( eatFoodyImages[] )
.asBitmap()
.into( target );
}
這段代碼的第一部分建立了一個字段對象,聲明了一個方法,即一旦 Glide 已加載并處理完圖像,它将被調用。這個回調方法傳了 Bitmap 作為一個參數。你之後便可以使用這個 Bitmap 對象,無論你要怎樣用它。這段代碼的第二部分是我們如何通過 Glide 用 targets:和 ImageView 用法完全相同的!你既可以傳一個 Target 也可以傳一個 ImageView 參數給 .into() 方法。Glide 自己将會處理并傳回結果給任何一個。這裡有一些不同的是,我們添加了 .asBitmap(),它強制 Glide 去傳回一個 Bitmap 對象。記住,Glide 也可以加載 Gif 或 video 的。為了防止 target 的沖突(我們需要 Bitmap) 和未知資源在網絡背後的 URL(可能是一個 Gif),我們可以調用 .asBitmap() 告訴 Glide 我們需要一個圖像。
除了知道如何實作一個簡單版本的 Glide 的 Target 回調系統,你要學會額外兩件事。
首先是 SimpleTarget 對象的字段聲明。從技術上來說,Java/Android 會允許你在 .into() 方法中去聲明 target 的匿名内部類。然而,這大大增加了這樣一個可能性:即在 Glide 做完圖檔請求之前, Android 垃圾回收移除了這個匿名内部類對象。最終這可能會導緻一個情況,當圖像加載完成了,但是回調再也不會被調用。所請確定你所聲明的回調對象是作為一個字段對象的,這樣你就可以保護它避免被邪惡的 Android 垃圾回收機制回收 ;-)
第二個關鍵部分是 Glide 建造者中這行:.with(context)。 這裡的問題實際是 Glide 的功能:當你傳了一個 context,例如是目前應用的 activity,Glide 将會自動停止請求當請求的 activity 已經停止的時候。這整合到了應用的生命周期中通常是非常有幫助的,但是有時工作起來是困難的,如果你的 target 是獨立于應用的 activity 生命周期。這裡的解決方案是用 application 的 context: .with(context.getApplicationContext))。當應用資深完全停止時,Glide 才會殺死這個圖檔請求。請求記住,再說一次,如果你的請求需要在 activity 生命周期之外去做時,才用下面這樣的代碼:
private void loadImageSimpleTargetApplicationContext() {
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[]
.asBitmap()
.into( target2 );
}
Target 指定尺寸
另一個潛在的問題是,target 沒有指明大小。如果你你傳一個 ImageView 作為參數給 .into(),Glide 将會用 ImageView 的大小去限制圖像的大小。比如說,如果加載的圖檔是 x1000 像素的,但是 ImageView 隻有 x250 像素,Glide 将會減少圖檔的尺寸去節省時間和記憶體。很顯然,在和 target 協作的時候并沒有這麼做,因為我們并沒有已知的大小。然而,如果你有一個指定的大小,你可以提高回調。如果你知道這種圖檔應該要多大,你應該在你的回調聲明中指定它以節省一些記憶體。
private SimpleTarget target2 = new SimpleTarget<Bitmap>( , ) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
imageView2.setImageBitmap( bitmap );
}
};
private void loadImageSimpleTargetApplicationContext() {
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[] )
.asBitmap()
.into( target2 );
}
還有很多方法以後再學習…