Google推薦——Glide使用詳解

零丘跌、前言

本文所使用的Glide版本為3.7.0
如果需要使用V4的最新版本請參考Glide V4使用指南

一、簡介

Glide初烘,一個被google所推薦的圖片加載庫罢缸,作者是bumptech。這個庫被廣泛運用在google的開源項目中颊艳,包括2014年的google I/O大會上發(fā)布的官方app茅特。(PS:眾所周知的簡介就到此為止了)

Glide 對于 Android SDK 的最低要求是 API level 10

Glide滑行的意思,可以看出這個庫的主旨就在于讓圖片加載變的流暢∑逭恚現(xiàn)在被廣泛使用白修,當然還是有很多開發(fā)者使用Square公司的picasso,也有兩個庫的對比

原文鏈接:http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

譯文鏈接:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0327/2650.html

二重斑、使用

(一)導入

在AndroidStudio上添加依賴非常簡單

dependencies {  
    implementation 'com.github.bumptech.glide:glide:3.7.0'  
    implementation 'com.android.support:support-v4:23.2.1'  
}  

Glide 也支持 Maven 項目形式:

<dependency>
  <groupId>com.github.bumptech.glide</groupId>
  <artifactId>glide</artifactId>
  <version>3.7.0</version>
</dependency>
<dependency>
  <groupId>com.google.android</groupId>
  <artifactId>support-v4</artifactId>
  <version>r7</version>
</dependency>

如果是Eclipse使用去下載Glide的jar在項目中使用就可以了兵睛,jar的鏈接https://github.com/bumptech/glide/releases

(二)基礎(chǔ)使用

基本方法

Glide的一個完整的請求至少需要三個參數(shù),代碼如下:

String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
    .load(url)
    .into(imageView);
  • with(Context context) - 需要上下文窥浪,這里還可以使用 Activity祖很、FragmentActivity、android.support.v4.app.Fragment漾脂、android.app.Fragment 的對象假颇。將 Activity/Fragment 對象作為參數(shù)的好處是,圖片的加載會和 Activity/Fragment 的生命周期保持一致骨稿,例如:onPaused 時暫停加載笨鸡,onResume 時又會自動重新加載。所以在傳參的時候建議使用 Activity/Fragment 對象啊终,而不是 Context镜豹。
  • load(String url) - 這里我們所使用的一個字符串形式的網(wǎng)絡圖片的 URL,后面會講解 load() 的更多使用方式
  • into(ImageView imageView) - 你需要顯示圖片的目標 ImageView

占位圖設(shè)置

偶爾出現(xiàn)圖片加載慢或者加載不出來的情況是難以避免的蓝牲,所以為了 UI 能好看一些趟脂,我們會使用占位圖。Glide 也為我們提供這種方法 placeHolder() 和 error()

String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
    .load(url)
    .placeholder(R.drawable.place_image)//圖片加載出來前例衍,顯示的圖片
    .error(R.drawable.error_image)//圖片加載失敗后昔期,顯示的圖片
    .into(imageView);

注:這里需要注意一點,placeholder() 和 error() 的參數(shù)都是只支持 int 和 Drawable 類型的參數(shù)佛玄,這種設(shè)計應該是考慮到使用本地圖片比網(wǎng)絡圖片更加合適做占位圖硼一。

縮略圖

Glide 的縮略圖功能在這里不得不說,和占位圖略有不同梦抢,占位圖必須使用資源文件才行般贼,而縮略圖是動態(tài)的占位圖可以從網(wǎng)絡中加載。縮略圖會在世紀請求加載完成或者處理完之后才顯示哼蛆。在原始圖片到達之后蕊梧,縮略圖不會取代原始圖片,只會被抹除腮介。

Glide 為縮略圖提供了2種不同的加載方式肥矢,比較簡單的方式是調(diào)用 thumbnail() 方法,參數(shù)是 float 類型叠洗,作為其倍數(shù)大小甘改。例如,你傳入 0.2f 作為參數(shù)灭抑,Glide 將會顯示原始圖片的20%的大小十艾,如果原圖是 1000x1000 的尺寸,那么縮略圖將會是 200x200 的尺寸名挥。為縮略圖明顯比原圖小得多疟羹,所以我們需要確保 ImageView 的 ScaleType 設(shè)置的正確。

Glide.with( context )
    .load( url )
    .thumbnail( 0.2f )
    .into( imageView );

注:應用于請求的設(shè)置也將應用于縮略圖禀倔。

使用 thumbnail() 方法來設(shè)置是簡單粗暴的榄融,但是如果縮略圖需要通過網(wǎng)絡加載相同的全尺寸圖片,就不會很快的顯示了救湖。所以 Glide 提供了另一種防止去加載縮略圖愧杯,先看代碼

private void loadImageThumbnailRequest(){
    // setup Glide request without the into() method
    DrawableRequestBuilder<String> thumbnailRequest = Glide.with( context ).load( url );
    // pass the request as a a parameter to the thumbnail request
    Glide.with( context )
        .load( url )
        .thumbnail( thumbnailRequest )
        .into( imageView );
}

與第一種方式不同的是,這里的第一個縮略圖請求是完全獨立于第二個原始請求的鞋既。該縮略圖可以是不同的資源圖片力九,同時也可以對縮略圖做不同的轉(zhuǎn)換,等等...

動畫開關(guān)

動畫效果可以讓圖片加載變得更加的平滑邑闺,crossFade() 方法強制開啟 Glide 默認的圖片淡出淡入動畫跌前,當前版本3.7.0是默認開啟的。crossFade() 還有一個重載方法 crossFade(int duration)陡舅〉峙遥可以控制動畫的持續(xù)時間,單位ms靶衍。動畫默認的持續(xù)時間是300ms灾炭。既然可以添加動畫,那肯定就可以設(shè)置沒有任何淡出淡入效果颅眶,調(diào)用 dontAnimate()

Glide.with(context)
    .load(url)
    .crossFade()//或者使用 dontAnimate() 關(guān)閉動畫
    .placeholder(R.drawable.place_image)
    .error(R.drawable.error_image)
    .into(imageView);

PS:Glide 是可以自定義動畫效果的蜈出,這個在后面會講解

圖片大小與裁剪

在項目開發(fā)過程中,指定圖片顯示大小長長可能用到涛酗,畢竟從服務器獲取的圖片不一定都是符合設(shè)計圖的標準的铡原。我們在這里就可以使用 override(width,height) 方法偷厦,在圖片顯示到 ImageView 之前,重新改變圖片大小燕刻。

Glide.with(context)
    .load(url)
    .override(width,height)//這里的單位是px
    .into(imageView);

在設(shè)置圖片到 ImageView 的時候沪哺,為了避免圖片被擠壓失真,ImageView 本身提供了 ScaleType 屬性酌儒,這個屬性可以控制圖片顯示時的方式,具體的屬性使用還是去搜索吧枯途!Glide 也提供了兩個類似的方法 CenterCrop() 和 FitCenter()忌怎,CenterCrop() 方法是將圖片按比例縮放到足矣填充 ImageView 的尺寸,但是圖片可能會顯示不完整酪夷;而 FitCenter() 則是圖片縮放到小于等于 ImageView 的尺寸榴啸,這樣圖片是顯示完整了,但是 ImageView 就可能不會填滿了晚岭。

注:其實 Glide 的 CenterCrop() 和 FitCenter() 這兩個方法分別對應 ImageView 的 ScaleType 屬性中的 CENTER_CROP 和 FIT_CENTER 命名基本一致鸥印。

圖片的緩存處理

為了更快的加載圖片,我們肯定希望可以直接拿到圖片坦报,而不是進行網(wǎng)絡請求库说,所以我們需要緩存。Glide 通過使用默認的內(nèi)存和磁盤緩存來避免不必要的網(wǎng)絡請求片择,之后我們再詳細的去看它的實現(xiàn)潜的。

內(nèi)存緩存

內(nèi)存緩存是 Glide 默認幫我們做了的,除非你不需要字管,可以調(diào)用 skipMemoryCache(true) 告訴 Glide 跳過內(nèi)存緩存啰挪。這樣 Glide 就不會把這張圖片放到內(nèi)存緩存中,該方法只影響內(nèi)存緩存嘲叔。(不要問調(diào)用skipMemoryCache(false)的問題亡呵,Glide 是默認將圖片放入內(nèi)存緩存中的)

磁盤緩存

磁盤緩存也是默認開啟的,當然也是可以關(guān)閉的硫戈,不過關(guān)閉的方式略微有點不一樣锰什。

Glide.with(context)
    .load(url)
    .skipMemoryCache(true)
    .diskCacheStrategy( DiskCacheStrategy.NONE )
    .into(imageView);

上面這段代碼將內(nèi)存緩存和磁盤緩存都禁用了,這里使用枚舉 DiskCacheStrategy.NONE 將磁盤緩存禁用了掏愁,這里涉及到了自定義磁盤緩存行為歇由,我們接下來就講解這個。

自定義磁盤緩存行為

使用 DiskCacheStrategy 可以為 Glide 配置磁盤緩存行為果港。Glide 的磁盤緩存比較復雜沦泌,這也是在圖片加載可以比 Picasso 的原因(之一)。Picasso 只緩存了全尺寸的圖片辛掠,而 Glide 的不同之處在于谢谦,Glide 不僅緩存了全尺寸的圖释牺,還會根據(jù) ImageView 大小所生成的圖也會緩存起來。比如回挽,請求一個 800x600 的圖加載到一個 400x300 的 ImageView 中没咙,Glide默認會將這原圖還有加載到 ImageView 中的 400x300 的圖也會緩存起來。

DiskCacheStrategy 的枚舉意義:

  • DiskCacheStrategy.NONE 什么都不緩存
  • DiskCacheStrategy.SOURCE 只緩存全尺寸圖
  • DiskCacheStrategy.RESULT 只緩存最終的加載圖
  • DiskCacheStrategy.ALL 緩存所有版本圖(默認行為

這只是舉個例子而已

Glide.with(context)
    .load(url)
    .diskCacheStrategy( DiskCacheStrategy.SOURCE )
    .into(imageView);

圖片請求的優(yōu)先級

同一時間加載多個圖片千劈,App 將難以避免這種情況祭刚。如果這個時候我們希望用戶的體驗更好,往往會選擇先加載對于用戶更加重要的圖片墙牌。Glide 可以調(diào)用 .priority() 方法配合 Priority 枚舉來設(shè)置圖片加載的優(yōu)先級涡驮。

//設(shè)置 HIGH 優(yōu)先級
Glide.with( context )
    .load( highPriorityImageUrl )
    .priority (Priority.HIGH )
    .into( imageView );
//設(shè)置 LOW 優(yōu)先級
Glide.with( context )
    .load( lowPriorityImageUrl )
    .priority( Priority.LOW )
    .into( imageView );
  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIAT

這里有一點需要注意,優(yōu)先級并不是完全嚴格遵守的喜滨。Glide 將會用他們作為一個準則捉捅,盡可能的處理這些請求,但是不能保證所有的圖片都會按照所有要求的順序加載虽风。

顯示 Gif 和 Video

顯示 GIf 對于 Glide 來說一個比較特別的功能(至少 Picasso 暫時還不行)而且使用起來非常簡單

String gifUrl = "http://i2.mhimg.com/M00/0E/AE/CgAAilTPWJ2Aa_EIACcMxiZi5xE299.gif";
Glide.with( context )
    .load( gifUrl )
    .placeholder( R.drawable.default )
    .error( R.drawable.error )
    .into( imageView );

這段代碼還有點問題棒口,如果加載的不是一張 gif 圖的話,是沒有辦法顯示的辜膝。

Glide.with( context )
    .load( gifUrl )
    .asGif()
    .error( R.drawable.error )
    .into( imageView );

做以上修改无牵,如果圖片類型不是 Gif 圖的話就會當作 load 失敗來處理,因此 error() 會被回調(diào)内舟。即使這個url的圖片是好的合敦,也是不會顯示的。當然验游,如果你想顯示 Gif 但只是向現(xiàn)實靜態(tài)的圖片你就可以這么做

Glide.with( context )
    .load( gifUrl )
    .asBitmap()
    .error( R.drawable.error )
    .into( imageView );

僅僅是顯示 Gif 的第一幀圖像充岛,這樣就可以保證圖片的正常顯示了。

還有一個神奇的功能耕蝉,Glide 還能顯示視頻崔梗!But...只能夠顯示手機本地的視頻,要是向現(xiàn)實網(wǎng)絡上的視頻的話垒在,還是另尋他法吧蒜魄!

String filePath = "/storrage/emulated/0/Pictures/video.mp4";
Glide.with( context )
    .load( Uri.fromFile( new File( filePath ) ) )
    .into( imageView );

Glide 的基礎(chǔ)使用就講解到這了。

(三)進階使用

Target篇

到現(xiàn)在為止场躯,我們所涉及到的代碼都是直接加載圖片到 ImageView 中谈为。Glide 隱藏做了所有的網(wǎng)絡請求和后臺的線程處理,圖片準備好之后切回到 UI 線程刷新 ImageView踢关。也就是說 ImageView 在我們代碼的鏈式結(jié)構(gòu)中成為了最后一步伞鲫,但是如果我們需要獲取到 Bitmap 本身
的話我們就需要用到 Target 了。Target 其實就是整個圖片的加載的生命周期签舞,所以我們就可以通過它在圖片加載完成之后獲取到 Bitmap秕脓。

其實對于 Target 可以簡單的理解為回調(diào)柒瓣,本身就是一個 interface,Glide本身也為我們提供了很多 Target

所有Targets
SimpleTarget

直接上代碼

private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>() {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
        mImageView.setImageBitmap(resource);
    }
};

private void loadImageSimpleTarget() {
    Glide.with( thi s)
        .load( mUrl )
        .asBitmap()
        .into( mSimpleTarget );
}

首先創(chuàng)建了一個 SimpleTarget 的對象并且實現(xiàn)了 onResourceReady() 方法吠架,看方法名能知道是圖片加載完之后會調(diào)用該方法芙贫,參數(shù)就有我們需要的 Bitmap 。而使用 SimpleTarget 的對象的時候就像使用 ImageView 一樣傍药,作為參數(shù)傳給 into() 方法就行了磺平,Glide 會內(nèi)部去處理并返回結(jié)果給任何一個對象。這里我們?yōu)榱朔乐辜虞d Gif 拐辽、 Video 或者一些位置資源時與 mSimpleTarget 沖突褪秀,所以我們調(diào)用了 asBitmap() 方法,使其只能返回 Bitmap 對象薛训。

這里就有個問題了,如果我需要改變圖片的大小怎么辦仑氛?這點小問題 Glide 還是有考慮到的乙埃,加入原尺寸 1000x1000 的圖片,我們顯示的時候只需要是 500x500 的尺寸來節(jié)省時間和內(nèi)存锯岖,你可以在 SimpleTarget 的回調(diào)聲明中指定圖片的大小介袜。

private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>(500,500) {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
        mImageView.setImageBitmap(resource);
    }
};

從代碼中可以看到 SimpleTarget 的對象的聲明沒有使用匿名對象,而是單獨的聲明了一個變量出吹,這里是故意這么做的遇伞,如果使用匿名內(nèi)部類的方式創(chuàng)建 SimpleTarget 的對象,這樣會增大該對象在 Glide 完成圖片請求之前就被回收的可能性捶牢。

還記得前面說過 with() 方法傳入 Activity 或者 Fragment 時 Glide 的圖片加載會與他們的生命周期關(guān)聯(lián)起來鸠珠,但是如果我們使用 Target 的話,這個 Target 就有可能獨立于他們的生命周期以外秋麸,這時候我們就需要使用 context.getApplicationContext() 的上下文了渐排,這樣只有在應用完全停止時 Glide 才會殺死這個圖片請求。代碼如下

Glide.with(mContext.getApplicationContext())
        .load(mUrl)
        .asBitmap()
        .into(target);
ViewTarget

當我們使用 Custom View 時灸蟆,Glide 并不支持加載圖片到自定義 view 中的驯耻,使用 ViewTarget 更容易實現(xiàn)。

public class CustomView extends FrameLayout {
    private ImageView mImageView;

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mImageView = new ImageView(getContext());
        addView(mImageView , LayoutParams.MATCH_PARENT , LayoutParams.MATCH_PARENT);
    }

    public void setImage(Drawable drawable){
        mImageView.setImageDrawable(drawable);
    }
}

上面這個例子就沒有辦法直接使用 .into() 炒考,如果我們使用 ViewTarget 實現(xiàn)呢可缚!

public void loadImageTarget(Context context){
    CustomView mCustomView = (CustomView) findViewById(R.id.custom_view);

    ViewTarget viewTarget = new ViewTarget<CustomView,GlideDrawable>( mCustomView ) {
        @Override
        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
            this.view.setImage(resource);
        }
    };

    Glide.with(context)
            .load(mUrl)
            .into(viewTarget);
}

在 target 的 onResourceReady 回調(diào)方法中使用自定義 view 自己的方法去設(shè)置圖片,可以看到在創(chuàng)建 ViewTarget 的時候傳入了 CustomView 的對象斋枢。

還有其他Target的使用這里就不一一講述了帘靡,例如 AppWidgetTarget 、 NotificationTarget ...

Transformations篇

圖片顯示之前我們可能還需要對圖片進行處理操作杏慰,比如:圖片切圓角测柠,灰階處理等等炼鞠;這些需求我們通過 Transformations 操作 bitmap 來實現(xiàn),我們可以修改圖片的任意屬性:尺寸轰胁,范圍谒主,顏色,像素位置等等赃阀。其實我們之前已經(jīng)提到過兩個 Transformation 了霎肯,即 fitCenter 和 centerCrop ,這兩個是 Glide 已經(jīng)實現(xiàn)的榛斯。

接下來就要講講怎么樣來實現(xiàn)自己的 Transformation 观游,我們需要創(chuàng)建一個類去實現(xiàn) Transformation 接口,但是要實現(xiàn)這個方法還是比較復雜的驮俗,接口中 transform 方法提供的參數(shù) Resource<T> resource 不是那么好處理的懂缕。如果你只是想要對圖片(不是 Gif 和 video)做常規(guī)的 bitmap 轉(zhuǎn)換,我們推薦你使用抽象類 BitmapTransformation王凑。它簡化了很多的實現(xiàn)搪柑,這應該能覆蓋 95% 的應用場景啦。

下面的代碼實現(xiàn)了對圖片切圓角的操作索烹,其中 getId() 方法描述了這個 Transformation 的唯一標識工碾,為避免意外我們需要確保它是唯一的。

public class RoundTransformation extends BitmapTransformation {
    private float radius = 0f;

    public RoundTransformation(Context context) {
        this(context, 4);
    }

    public RoundTransformation(Context context, int px) {
        super(context);
        this.radius = px;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }

    private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null)
            return null;

        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName() + Math.round(radius);
    }

}

現(xiàn)在我們有了自己的 Transformation 就可以來看看怎么使用了百姓。

調(diào)用 .transform() 方法渊额,將自定義的 Transformation 的對象作為參數(shù)傳遞進去就可以使用你的 Transformation 了,這里也可以使用 .bitmaoTransform() 但是它只能用于 bitmap 的轉(zhuǎn)換垒拢。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(context , 20))
    //.bitmapTransform( new RoundTransformation(context , 20) )
    .into(mImageView);

如果我們需要同時執(zhí)行多個 Transformation 的話旬迹,我們不能使用鏈式的形式多次調(diào)用 .transform() 或 .bitmapTransform() 方法,即使你調(diào)用了求类,之前的配置就會被覆蓋掉舱权!我們可以直接傳遞多個轉(zhuǎn)換對象給 .transform() 或 .bitmapTransform() 。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(context , 20) 仑嗅,  new RotateTransformation(context , 90f))
    .into(mImageView);

這段代碼中我們把一個圖片切圓角宴倍,然后做了順時針旋轉(zhuǎn)90度處理。

下面是旋轉(zhuǎn)處理的代碼

public class RotateTransformation extends BitmapTransformation {

    private float rotateRotationAngle = 0f;

    public RotateTransformation(Context context, float rotateRotationAngle) {
        super( context );
        this.rotateRotationAngle = rotateRotationAngle;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Matrix matrix = new Matrix();

        matrix.postRotate(rotateRotationAngle);

        return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
    }

    @Override
    public String getId() {
        return getClass().getName() + Math.round(rotateRotationAngle);
    }
}

注:這里需要注意一點 .centerCrop() 和 .fitCenter() 也都是 Transformation 所以也是遵循同時使用多個 Transformation 的規(guī)則的仓技,即:當你使用了自定義轉(zhuǎn)換后你就不能使用 .centerCrop() 或 .fitCenter() 了鸵贬。

這里有一個 GLide Transformations 的庫,它提供了很多 Transformation 的實現(xiàn)脖捻,非常值得去看阔逼,不必重復造輪子對吧!
glide-transformations
這個庫有兩個不同的版本地沮,擴展版本包含了更多的 Transformation 嗜浮,它是通過設(shè)備的 GPU 來計算處理的羡亩,需要有額外的依賴,所以這兩個版本的設(shè)置有一點不同危融。還是根據(jù)需要再決定使用那個版本吧畏铆!

Animate篇

從圖像到圖像的平滑過渡是非常重要,Glide 中有一個標準動畫去柔軟的在你的 UI 中改變吉殃,但是我們現(xiàn)在希望設(shè)置自己的動畫辞居。

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <scale
        android:duration="@android:integer/config_longAnimTime"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1"/>
</set>

這是個 XML 動畫縮放動畫,圖片剛開始小的蛋勺,然后逐漸增大到原尺寸瓦灶。我們現(xiàn)在要應用到 Glide 加載圖片中去,調(diào)用 .animate() 方法傳入 XML 動畫的 id 即可抱完。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(this , 20))
    .animate( R.anim.zoom_in )
    .into(mImageView);

這種加載方式用在常規(guī)的 ImageView 上是沒有問題的贼陶,但如果使用的 Target 是一些自定義的時候就沒法好好的實現(xiàn)了。這時候我們就可以通過傳入實現(xiàn)了 ViewPropertyAnimation.Animator 接口的類對象來實現(xiàn)巧娱。

ViewPropertyAnimation.Animator animator = new ViewPropertyAnimation.Animator() {
    @Override
    public void animate(View view) {
        view.setAlpha( 0f );

        ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
        fadeAnim.setDuration( 2500 );
        fadeAnim.start();
    }
};

然后每界,我們只需要在 Glide 請求中設(shè)置這個動畫對象就ok了

Glide.with(context)
    .load(mUrl)
    .animate( animator )
    .into(viewTarget);

在 animate(View view) 中你的動畫對象方法中, 你可以做任何你想要對視圖做的事情家卖。自由的用你創(chuàng)建的動畫吧。

Modules篇

Glide 的 Module 是一個可以全局改變 Glide 的行為的東西庙楚,為了定制 Glide 的行為我們要去實現(xiàn) interface GlideModule 來寫我們自己的代碼上荡。

public class ExampleModule implements GlideModule{
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // todo
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // todo
    }
}

可以看到 GlideModule 為我們提供了兩個方法,這里我們主要使用的是 applyOptions(Context context, GlideBuilder builder) 馒闷, 我們自己的需要重新定義的代碼寫在該方法里就可以了酪捡。然后我們還需要去 AndroidManifest.xml 中使用 meta 聲明我們上面實現(xiàn)的 Module

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mrtrying.demoglide">

    <application>

        <meta-data
            android:name="com.mrtrying.demoglide.module.ExampleModule"
            android:value="GlideModule" />

        ...

    </application>

    ...

</manifest>

到這里我們就完成了 ExampleModule 的聲明,Glide 將會在工作是使用我們所定義的 Module

TIPS

  • 我們需要將 android:name 屬性改成 包名+類名 的形式纳账,這樣的引用才是正確的逛薇。如果你想刪掉 Glide Module,只需要刪除在 AndroidManifest.xml 中的聲明就可以了疏虫。Java 類可以保存永罚,說不定以后會用呢。如果它沒有在 AndroidManifest.xml 中被引用卧秘,那它不會被加載或被使用呢袱。

  • 定制 module 的話 Glide 會有這樣一個優(yōu)點:你可以同時聲明多個 Glide module。Glide 將會(沒有特定順序)得到所有的聲明 module翅敌。因為你當前不能定義順序羞福,請確保定制不會引起沖突!

這個過程走通了蚯涮,接下來我們來看看是怎么自定義的治专。applyOptions(Context context, GlideBuilder builder) 中有兩個參數(shù)卖陵, 我們通過使用 GlideBuilder 來實現(xiàn)我們的需求。先看看 GlideBuilder 中可用的方法

  • .setMemoryCache(MemoryCache memoryCache)
  • .setBitmapPool(BitmapPool bitmapPool)
  • .setDiskCache(DiskCache.Factory diskCacheFactory)
  • .setDiskCacheService(ExecutorService service)
  • .setResizeService(ExecutorService service)
  • .setDecodeFormat(DecodeFormat decodeFormat)

可以看到张峰,這個 GlideBuilder 對象給你訪問了 Glide 重要的核心組件泪蔫。接下來我們就要試著去使用這些方法

增加 Glide 的圖片質(zhì)量

在 Android 中有兩個主要的方法對圖片進行解碼:ARGB_8888 和 RGB_565 。前者為每個像素使用4個字節(jié)挟炬,后者每個像素僅使用2個字節(jié)鸥滨。ARGB_8888 的有時就是圖像質(zhì)量更高以及能儲存一個 alpha 通道。 Picasso 使用的就是 ARGB_8888 谤祖, Glide 默認使用低質(zhì)量的 RGB_565 婿滓,但是現(xiàn)在你就可以使用 Glide module 來改變圖片解碼規(guī)則。就象這樣

public class QualityModule implements GlideModule{
    @Override
    public void applyOptions(Context context , GlideBuilder builder){
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context , Glide glide){
        // nothing to do here
    }
}

這樣我們就簡單的增加了 Glide 的圖片質(zhì)量粥喜。

往往我們還會遇到一些情況凸主,希望 Glide 可以使用我們自己的網(wǎng)絡框架,我們就需要做一些事情來實現(xiàn)這個需求了额湘。Glide 的開發(fā)者不強制設(shè)置網(wǎng)絡庫給你卿吐,所以Glide可以說和 HTTPS 無關(guān)。理論上锋华,它可以與任何的網(wǎng)絡庫實現(xiàn)嗡官,只要覆蓋了基本的網(wǎng)絡能力就行。同樣是需要實現(xiàn) Glide 的 ModuleLoader 的接口毯焕,為了讓我們更加易用衍腥,Glide 為 OkHttp 和 Volley 兩個網(wǎng)絡庫提供了實現(xiàn)。

假設(shè)我要集成 OkHttp 作為 Glide 的網(wǎng)絡庫纳猫,我可以手動實現(xiàn)一個 GlideModule 也可以在 build.gradle 中添加依賴:

dependencies{
    //...
    
    // Glide
    compile 'com.github.bumptech.glide:glide:3.7.0'

    // Glide's OkHttp Integration
    compile 'com.github.bumptech.glide:okhttp-integration:1.4.0@aar'
    compile 'com.squareup.okhttp:okhttp:3.2.0'
}

Gradle 會自動合并必要的 GlideModule 到你的 AndroidManifest.xml 婆咸, Glide 會認可在 manifest 中存在,然后使用 OkHttp 做到的所有網(wǎng)絡連接芜辕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尚骄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侵续,更是在濱河造成了極大的恐慌倔丈,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件状蜗,死亡現(xiàn)場離奇詭異乃沙,居然都是意外死亡,警方通過查閱死者的電腦和手機诗舰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門警儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事蜀铲”吡穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵记劝,是天一觀的道長变姨。 經(jīng)常有香客問我,道長厌丑,這世上最難降的妖魔是什么定欧? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮怒竿,結(jié)果婚禮上砍鸠,老公的妹妹穿的比我還像新娘。我一直安慰自己耕驰,他們只是感情好爷辱,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朦肘,像睡著了一般饭弓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上媒抠,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天弟断,我揣著相機與錄音,去河邊找鬼趴生。 笑死阀趴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的冲秽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼矩父,長吁一口氣:“原來是場噩夢啊……” “哼锉桑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窍株,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤民轴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后球订,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體后裸,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年冒滩,在試婚紗的時候發(fā)現(xiàn)自己被綠了微驶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖因苹,靈堂內(nèi)的尸體忽然破棺而出苟耻,到底是詐尸還是另有隱情,我是刑警寧澤扶檐,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布凶杖,位于F島的核電站,受9級特大地震影響款筑,放射性物質(zhì)發(fā)生泄漏智蝠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一奈梳、第九天 我趴在偏房一處隱蔽的房頂上張望杈湾。 院中可真熱鬧,春花似錦颈嚼、人聲如沸毛秘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叫挟。三九已至,卻和暖如春限煞,著一層夾襖步出監(jiān)牢的瞬間抹恳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工署驻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奋献,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓旺上,卻偏偏與公主長得像瓶蚂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宣吱,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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