天天看點

Glide使用簡要說明

直接用代碼方式說下:

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 );
}
           

還有很多方法以後再學習…