1. 程式人生 > >Glide 4.7.1 使用詳解(一)

Glide 4.7.1 使用詳解(一)

目錄

前言

 使用方法

過度選項

變換

載入gif

總結

  • 前言

       圖片載入框架目前用的比較多的是picasso和glide, 其中谷歌官方也比較推薦glide, 在前文中已經分析了picasso的原理,在這裡我們就開始分析一下picasso的使用方法。其實glide的與picasso載入圖片的方法和方式還是大同小異的。尤其是在picasso也吸收了glide中一些優良的方法,差異越來越小。所以只在載入圖片這個模組中,其實差異不大,要根據自己專案需求來選擇哪個框架。要相信,木有最好的框架,只有最適合的。閒話少說,開始講glide的使用方法,因為glide版本比較多。 目前使用的是4.7.1,所以下面的內容就以這個版本為準。 對於以前的3.x要遷移到4.x請參考 

從v3升級到v4

  • Glide特點

      為什麼要使用glide呢,他總是有自己的優勢的,官方有自己的介紹,我這裡寫寫自己的體會:

     1 整合簡單,使用起來也很簡單,幾行程式碼搞定。

     2 支援多種格式的圖片,png,jpeg,jpg,webp,並且支援多個來源,檔案,網路,本地。

     3 它集成了activity,fragment的生命週期,實現了自動管理。相對於picasso這點要好一些。

     4 高效的快取和硬碟本地儲存效率。

  • Glide匯入

       首先提供一下github的原始碼:glide原始碼, 如果直接下載的話,版本是最新的, 我們可以在release中找自己需要的版本。使用glide首先在專案中新增依賴:

repositories {
  mavenCentral()
  google()
} 

implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'


//下面是需要的許可權
 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

       如果需要混淆新增:

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

# for DexGuard only
-keepresourcexmlelements manifest/application/[email protected]=GlideModule
  •  使用方法

         glide使用比較簡單,可以直接在activity,fragment,fragmentactivity中,與picasso類似,如果只是簡單的載入圖片,不做其他處理,glide只需要一行程式碼就搞定:

//url表示載入圖片地址,first表示的是顯示圖片的imageview
Glide.with(this).load(url).into(first);

      其中this,可以代表Activity,Fragment,Fragment,也可是Context等,我們可以看下這個函式的過載情況,with函式如果傳入的是fragment或者activity,那麼整個載入流程會與activity/fragment的生命週期繫結,比如onpause就會停止載入,onResumed的時候就重新載入。

      

       圖中的引數都可以直接使用。glide通過load方法載入圖片,glide可以載入多種形式的圖片,從來load也有多種過載形式:

         

   通過這些方法我們可以看出,可以載入多種形式的圖片 。例如我們載入assets資料夾中的earth.png的圖片可以如下:

Glide.with(this).load("file:///android_asset/earth.png").into(first);
  • 通過RequestOption設定屬性

       上面只是載入圖片的最基本的方法,在開發中肯定還有其他需求,比如佔位符或者容錯圖片,這個時候就需要通過RequestionOption來進行設定。 

RequestOptions options = new RequestOptions()
                .placeholder(R.mipmap.icon)	//載入成功之前佔位圖
                .error(R.mipmap.ic_launcher)	//載入錯誤之後的錯誤圖
                .override(100,100)	//指定圖片的尺寸
                .fitCenter()   //指定圖片的縮放型別為fitCenter (等比例縮放圖片,寬或者是高等於 
                                   ImageView的寬或者是高。是指其中一個滿足即可不會一定鋪滿 
                                     imageview)

                
                .centerCrop()//指定圖片的縮放型別為centerCrop (等比例縮放圖片,直到圖片的寬高都 
                                  大於等於ImageView的寬度,然後擷取中間的顯示。)

             
                .skipMemoryCache(true)	//不使用記憶體快取
                .diskCacheStrategy(DiskCacheStrategy.ALL)	//快取所有版本的影象
                .diskCacheStrategy(DiskCacheStrategy.NONE)	//不使用硬碟本地快取
                .diskCacheStrategy(DiskCacheStrategy.DATA)	//只快取原來解析度的圖片
                .diskCacheStrategy(DiskCacheStrategy.RESOURCE)	//只快取最終的圖片
                ;

     通過如下程式碼的方式進行設定requestionoption

//通過apply方法將設定的屬性新增到glide

Glide.with(this).load(firstUrl).apply(requestOptions).into(first);

      

       這是一個imageview載入圖片的兩種設定方式。第一個是centercrop的方式。會擷取中間部分鋪滿imageview,第二個是fitcenter方法,鋪滿了寬就結束了。整個紫色的部分是imageview的background,這樣是為了更明顯的看出效果。其他幾個設定記憶體屬性的情況,在註釋中已經說明了。其實很簡單,只是看需求是不是每次都需要從網路獲取,或者在快取中獲取。這個就不說了。

  •  載入圖片的回撥函式

        無論設定怎樣的屬性,有時候我們需要圖片載入的進度, glide也提供了相應的回撥函式:

Glide.with(this).load(firstUrl).apply(requestOptions).listener(new RequestListener<Drawable>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                Log.e(TAG," the task is err0r");
                return false;
            }

            @Override
            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                Log.e(TAG,"&&&&&&&&&&&&&&&&&&&&&&&&the task is ok");
                return false;
            }
        }).into(first);

        這就是新增的回撥方法,這個回到方法只有成功,和失敗的回撥,而有的時候我們的需求需要展示下載圖片的進度, 這個時候,這個回撥就無法滿足需求了。這就需要我們自己設定了。這就涉及到了glide的自定義模組,受於篇幅的限制,這篇只講簡單的使用,這個功能在後面的部落格裡講。

  • 過度選項

      對於crossfade()和animate()這樣的函式,控制從佔位符到圖片和/或縮圖到全圖的交叉淡入和其他型別變換的選項,被移動到了TransitionOpetion中. 如果你想移除任何預設的過渡,可以使用 TransitionOptions.dontTransition()。過渡動畫通過 RequestBuilder 應用到請求上. 在4.0的版本上,載入圖片的漸入漸出效果已經不是預設效果了。每個請求必須手動應用過渡。要為一個特定的載入應用一個交叉淡入變換效果,你可以使用:

import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;

Glide.with(fragment)
  .load(url)
  .transition(withCrossFade())
  .into(imageView);
或:

Glide.with(fragment)
  .load(url)
  .transition(
      new DrawableTransitionOptions
        .crossFade())
  .into(imageView);
  • 變換

     在專案中我們經常有特殊的需求,比如圓角,比如灰化等等,這個時候需要對圖片進行處理,這部分功能,在glide中通過Transformation來進行設定。

RequestOptions requestOptions = new RequestOptions();
requestOptions.override(100,100).fitCenter()
                .transforms(new GlideColorTransformation(),new RoundedCorners(20));

     通過requestionOption的transform方法來進行設定,GlideColorTransformation()這個類是我自己寫的關於圖片灰化處理的類,在前文的picasso的方法使用文章中有貼出來。而這裡的其實原理是一樣的,只不過需要特別注意的是變換前的bitmap不需要釋放

public class GlideColorTransformation extends BitmapTransformation {
    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap source, int outWidth, int outHeight) {
        int width = source.getWidth();
        int height = source.getHeight();

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);

        canvas.drawBitmap(source, 0, 0, paint);
        //這裡要特別注意,picasso重寫的時候,變換的前的bitmap要自己釋放,而glide不需要是否,否則也會有錯。
    //   source.recycle();
        return bitmap;
    }

    @Override
    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {

    }

    我們設定圖片的變換,有的時候需要一次變化就可以,有的時候時候就需要多次處理才可以。而看transform,和transforms兩個函式,可以看到分別對應一個和多個變換。而glide也提供了一些圖片的變化類,使用的時候直接用不需要我們重寫。

       這個是原始碼中com.bumptech.glide.load.resource.bitmap目錄下的類,比如CircleCrop時候圖片圓形化變化,centercrop拉伸等等。大家可以自己看看。需要的時候直接拿來用。

  • 自定義GlideModule

       與很多優秀的開源框架一樣,glide也支援自定義屬性來滿足開發者的需求。而glide的自定義首先在AndroidManifest.xml中通過meta宣告。

 <meta-data
            android:name="com.project.practice.imageviewloader.MyGlideModule"
            android:value="GlideModule"/>

其中那麼指的是類的完整路徑,value的值必須是GlideMoudle。 

public class MyGlideModule implements GlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_RGB_565));
    }

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {

    }
}

這個是自己寫的很簡單的一個自定義的glidemodule,因為4.0以上的版本,對於下載圖片的解碼方式由變化為了: ARGB_8888, 在之前的版本使用的是RGB_565,使用565佔用的記憶體只是8888的一半,但是呢,對於圖片的色質有影響,所以4.0後又恢復到了8888, 這樣畫質沒問題了,但是記憶體不可避免的變大了。我這裡將他的解碼方式重新變為565.

  • 載入gif

    眾所周知的情況,glide比picasso多的功能是支援gif的載入。其實也是一行程式碼搞定:

Glide.with(this).asGif().load(R.mipmap.qingdannanniu).apply(requestOptions).into(first);

        其中asGif()的方法就是告訴glide,載入的將是一個gif的格式。在載入網路圖片的時候,預設是靜態的png等格式,所以我們要通過這個函式通知Glide。

  • 總結

        到這裡,基本把常用的方法都大致說了一下。後面會寫具體的分析。 如果有什麼遺漏或者不正確的地方,請不吝賜教,留下評論。