Glide 知識梳理(1) 基本用法

1、概述

本文的內容大部分都是參考了下面這個連接中Glide分類的文章:android

https://futurestud.io/tutorials/glide-getting-startedgit

爲了區分,咱們這篇只介紹一些基本用法,掌握這些基本就能夠在項目中使用Glide了,而關於如何自定義Target/Glide Module等高級的用法,以後再進行討論。github

2、導入依賴包&加載網絡靜態圖片

在使用前,首先須要在build.gradle中引入:緩存

dependencies {
    //....
    compile 'com.github.bumptech.glide:glide:3.7.0'
    //...
}
複製代碼

下面是Glide加載一張網絡靜態圖片最基本的用法:bash

Glide
.with(this) //傳入關聯的Context,若是是Activity/Fragment,那麼它會根據組件當前的狀態來控制請求。
.load("http://i.imgur.com/DvpvklR.png") //須要加載的圖片,大多數狀況下就是網絡圖片的連接。
.into(getImageView()); //用來展示圖片的ImageView.
複製代碼

3、load的其它用法

在第二章的例子當中,當咱們調用完.with(Context context)以後,會返回一個RequestManager對象,以前咱們就是調用它的load(String string)方法,除此以外,還提供了下面的這些load方法,load方法最終會返回一個DrawableTypeRequest<xxxx>,而xxx就是咱們傳入的參數的類型: 服務器

  • load(byte[] model),從byte[]中讀取
  • load(File file),從File中讀取
  • load(Integer resourceId),從resourceId中讀取
  • load(String string),從String當中讀取,這個通常對應於網絡圖片的連接,這個圖片有多是普通的圖片,也多是一個Gif,當咱們須要展現一個Gif圖片時,只須要像加載普通圖片同樣就能夠了,在加載完以後,這個Gif會被自動播放。
  • load(T model),從任意類型T的中讀取,這個後面講到自定義Model時再介紹
  • load(Uri uri),從Uri類型中讀取,這個Uri必須可以被UriLoader識別。
  • loadFromMediaStore(Uri uri),從媒體設備的Uri中讀取,這個方法用來展現一個本地媒體視頻的縮略圖,也就是視頻的第一幀,須要注意,這個連接只能是本地的,網絡上視頻連接地址是無效的。

下面是各個方法加載的例子:網絡

//從byte[]中加載.
    public void loadByteArray(View view) {
        Bitmap sourceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.book_local);
        ByteArrayOutputStream bArrayOS = new ByteArrayOutputStream();
        sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, bArrayOS);
        sourceBitmap.recycle();
        byte[] byteArray = bArrayOS.toByteArray();
        try {
            bArrayOS.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Glide.with(this)
                .load(byteArray)
                .into(mImageView);
    }
    //從File中加載.
    public void loadFile(View view) {
        String storePath = "mnt/sdcard/book_local.jpg";
        File file = new File(storePath);
        Glide.with(this)
                .load(file)
                .into(mImageView);
    }
    //從resourceId中加載.
    public void loadResourceId(View view) {
        Glide.with(this)
                .load(R.drawable.book_local)
                .into(mImageView);
    }
    //從普通url中加載.
    public void loadNormalUrl(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .into(mImageView);
    }
    //從gif加載.
    public void loadGif(View view) {
        Glide.with(this)
                .load("http://s1.dwstatic.com/group1/M00/66/4D/d52ff9b0727dfd0133a52de627e39d2a.gif")
                .diskCacheStrategy(DiskCacheStrategy.SOURCE) //要加上這句,不然有可能會出現加載很慢,或者加載不出來的狀況.
                .into(mImageView);
    }
    //從本地媒體視頻中加載.
    public void loadMedia(View view) {
        String storePath = "mnt/sdcard/media.mp4";
        File file = new File(storePath);
        Glide.with(this)
                .load(Uri.fromFile(file))
                .into(mImageView);
    }
複製代碼

4、佔位圖片和錯誤圖片

4.1 顯示佔位圖片

有時候因爲網絡緣由,致使請求耗時,此時就須要在獲得圖片資源以前,採用一個佔位圖片,這樣就不會顯得界面太空,placeHolder就是作這個事的,當咱們調用了into方法以後,若是須要從網絡上獲取圖片,那麼它會先展現placeHolder設置的圖片,placeHolder除了支持傳入resourceId,還支持直接傳入一個Drawable對象。框架

@Override
    public DrawableRequestBuilder<ModelType> placeholder(int resourceId) {
        super.placeholder(resourceId);
        return this;
    }
    @Override
    public DrawableRequestBuilder<ModelType> placeholder(Drawable drawable) {
        super.placeholder(drawable);
        return this;
    }
複製代碼

使用placeHolder的例子:ide

public void loadHolder(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .placeholder(R.drawable.book_placeholder)
                .into(mImageView);
    }
複製代碼

4.2 顯示錯誤圖片

有時候,當咱們請求網絡圖片失敗時,咱們但願給用戶一些提示,這時候給它設置一些回調,並在回調當中進行處理。可是通常狀況下,咱們顯示一個表示錯誤的本地圖片就能夠了,爲了和前面加載時的佔位圖片區分,它提供了另外一個error()方法,和placeHolder相似,咱們能夠給它傳入一個resourceId或者Drawable對象。gradle

public void loadHolderError(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png") 
                .asGif()  //爲了模擬加載失敗的狀況.
                .placeholder(R.drawable.book_placeholder)
                .error(R.drawable.book_error)
                .into(mImageView);
    }
複製代碼

上面爲了模擬失敗的狀況,咱們傳入了一個png的連接,可是指定爲加載asGif()資源。 咱們發現它會先展現placeHolder的資源,再展現error的資源。

4.3 定義圖片切換動畫

不管是placeHolder仍是error,都會涉及到切換ImageView的圖片,這時咱們能夠經過設置一個動畫來讓這個切換的過程顯得不那麼突兀,默認狀況下動畫是開啓的,crossFade有下面這三個重載方法:

  • crossFade():採用默認動畫和默認時長。
  • crossFade(int duration):採用默認動畫,自定義時長。
  • crossFade(int animationId, int duration):採用自定義動畫,並自定義時長。
public void loadCustomCrossFade(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .placeholder(R.drawable.book_placeholder)
                .crossFade(5000) //改變的時長.
                .into(mImageView);
    }
複製代碼

4.4 關閉切換動畫

固然咱們也能夠經過dontAnimate,來關閉動畫,這樣在切換的時候就不會出現動畫。

public void loadNoCrossFade(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .placeholder(R.drawable.book_placeholder)
                .dontAnimate()
                .into(mImageView);
    }
複製代碼

5、得到圖片資源後,進行裁剪

5.1 裁剪

Picasso相比,Glide提供了一種更加高效的處理方式,它會把內存和緩存中的圖片限制到所展現的ImageView的返回內,Picasso也能夠實現這一功能,可是須要調用fit()方法。在使用Glide時,若是咱們不但願它自動地去匹配ImageView的寬高,那麼能夠調用override(width, height),這樣圖片資源在被展現以前就會裁剪爲指定的大小。

這個方法還有另外一種場景,就是當咱們確切的知道須要加載多大的圖片,可是此時ImageView的寬高並無獲得。

5.2 定義裁剪的方式

由於有時候採用override直接裁剪圖片有可能致使只裁剪到了沒必要要的信息,所以Glide還提供了兩個相似於ImageView中的scaleType屬性:

  • centerCrop:使原始的圖片的寬高按同等比例放大到override所指定的大小,並裁剪到多餘的部分,這時最終的圖片資源的大小爲(width, height)
  • fitCenter:使得原始圖片的寬高放大到小於等於override所指定的寬高,所以,咱們最終獲得圖片的大小有可能不爲(width, height),也就是說不會撐滿整個ImageView。 下面是相關的代碼:
public void loadOverride(View view) {
        Glide.with(this)
                .load(R.drawable.shader_pic)
                .override(20, 20)
                .into(mImageView);
    }

    public void loadOverrideCenterCrop(View view) {
        Glide.with(this)
                .load(R.drawable.shader_pic)
                .override(20, 20)
                .centerCrop()
                .into(mImageView);
    }

    public void loadOverrideFitCenter(View view) {
        Glide.with(this)
                .load(R.drawable.shader_pic)
                .override(20, 20)
                .fitCenter()
                .into(mImageView);
    }
複製代碼

5.3 和ImageViewscaleType的關係

因爲ImageView的展現還須要受android:scaleType的影響,這裏狀況有不少,因此上面裁剪出來,並非說在ImageView裏面展現就是20 * 20,具體會出現的狀況不少,這個以後再專門分析。

6、Gif圖片

在第二節中,咱們簡單的介紹瞭如何用Glide展現Gif圖片的展現,下面咱們深刻地討論一下其它兩點。

5.1 asGif()

有時候,咱們獲取的Gif圖片連接是服務器配置的,所以咱們沒法知道這個連接究竟是不是一個Gif圖片。這時咱們能夠配置一個asGif()選項,這樣Glide就會知道咱們是須要加載一個Gif圖片,當這個連接不是Gif時,加載就會失敗,若是咱們定義了.error(xxx),就會展現這個失敗的圖片。 例如,下面這段代碼就會失敗:

public void loadHolderError(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")  //傳入的是一個靜態圖片的連接.
                .asGif()  //爲了模擬加載失敗的狀況.
                .placeholder(R.drawable.book_placeholder)
                .error(R.drawable.book_error)
                .into(mImageView);
    }
複製代碼

5.2 asBitmap()

如今討論另一種狀況,在列表當中,雖然咱們得到的是Gif連接,可是咱們但願這時候不讓它播放,這時候就能夠指定asBitmap(),那麼就只會展現Gif圖片的第一幀。

5.3 定義緩存

若是咱們使用了.diskCacheStrategy(DiskCacheStrategy.SOURCE),那麼Gif資源的加載將會更快。

6、緩存策略

對於任何一個網絡圖片加載框架來講,緩存無疑是最關鍵的部分,Glide使用了內存和磁盤緩存來避免沒必要要的網絡請求,同時它也提供了一系列地接口讓使用者自定義緩存策略。

6.1 內存緩存策略

默認狀況下,Glide會將圖片資源緩存到內存當中。而若是使用了skipMemoryCache(true)Glide不會將這張圖片緩存到內存當中。 有一點須要注意:若是以前對某個指向url的圖片使用了內存緩存,後面又用skipMemoryCache(true)聲明想讓同一個url不緩存到內存中,那麼是不會生效的。

6.2 磁盤緩存策略

當某個圖片變化很快時,咱們有可能不須要將它緩存到磁盤當中,咱們能夠採用diskCacheStrategy(int mode)來定義緩存的策略,Glide默認狀況下既會緩存原始的圖片,也會緩存解析後的圖片,舉個例子,假如服務器上的圖片是1000 * 1000,而ImageView的大小隻有500 * 500,默認狀況下Glide會緩存這兩個版本的圖片,咱們能夠設定的磁盤緩存類型有下面四種:

  • DiskCacheStrategy.NONE:不緩存
  • DiskCacheStrategy.SOURCE:只緩存原始大小的圖片,也就是1000 * 1000
  • DiskCacheStrategy.RESULT:只緩存解析以後的圖片,也就是上面500 * 500的圖片,也就是說假如咱們有兩個不一樣大小的ImageView,用他們加載同一個url的圖片,那麼最終磁盤當中會有兩份不一樣大小的圖片資源。
  • DiskCacheStrategy.ALL:緩存全部版本的圖片。

如今咱們介紹一下采用了DiskCacheStrategy.RESULT後的緩存文件名的命名策略,具體能夠參考下面這篇文章:

https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation

緩存文件的命名會依賴於四個部分:

  • DataFechergetId()方法的返回值,通常狀況下就是Data ModeltoString方法。對於傳入String類型的網絡連接而言,就是url,而若是是File,那麼就是Filepath
  • 目標的寬高,若是定義了override(width, height),那就是指定的數值,默認狀況下是TargetgetSize()方法,也就是ImageView的寬高。
  • 用來加載和緩存圖片的encodersdecoderstoString方法。
  • 在加載時的可選簽名,這個方法在某些特殊的場景下頗有用,例如加載的url沒有變,可是服務器上這個url對應的圖片資源更新了,咱們就能夠經過.signature(xxx)來刷新緩存。

6.3 兩種策略的關係

上面咱們討論了兩種緩存策略的定義,這兩種策略是相互獨立的,默認狀況下內存的緩存爲打開,而磁盤的緩存策略爲DiskCacheStrategy.ALL

7、請求優先級

有時候,在同一個界面上咱們會展現多個圖片,而爲了用戶體驗,那麼某個圖片咱們但願先加載出來,這時候就能夠採用.priority(int priority)來定義請求的優先級,固然,這些優先級只是給Glide做爲參考,由於還涉及到圖片的大小,服務器的響應事件和網絡環境等因素,最後圖片展現的順序並不必定是根據優先級來的,可選的優先級包括:

  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIATE

8、縮略圖

前面,咱們介紹了placeHolder,它能夠指定一個本地資源,用來在網絡資源加載完成以前進行展現,而thumbnails則能夠認爲是一個動態的placeHolder,與placeHolder不一樣,咱們能夠給它指定一個網絡圖片連接。若是這個縮略圖請求在load請求以前返回那麼,那麼會先展現這個圖片,等到load請求返回以後,這個圖片就會消失。假如縮略圖的請求在load請求以後返回,那麼請求結果會被丟棄掉。 Glide提供了兩種指定縮略圖的方式:

8.1 Simple Thumbnails

public void loadScaleThumbnail(View view) {
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .thumbnail(0.1f)
                .into(mImageView);
    }
複製代碼

8.2 Complete Different Request

thumbnails還支持傳入一個Glide Request做爲參數,這個請求和本來的請求是相互獨立的,咱們能夠給它指定一個徹底不一樣的url、緩存策略、大小等等。

public void loadRequestThumbnail(View view) {
        DrawableRequestBuilder<String> thumbnailRequest = Glide
                .with(this)
                .load("http://i.imgur.com/DvpvklR.png");
        Glide.with(this)
                .load("http://s1.dwstatic.com/group1/M00/66/4D/d52ff9b0727dfd0133a52de627e39d2a.gif")
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .thumbnail(thumbnailRequest)
                .into(mImageView);
    }
複製代碼
相關文章
相關標籤/搜索