Glide 4.7.1 使用詳解(一)
目錄
-
前言
圖片載入框架目前用的比較多的是picasso和glide, 其中谷歌官方也比較推薦glide, 在前文中已經分析了picasso的原理,在這裡我們就開始分析一下picasso的使用方法。其實glide的與picasso載入圖片的方法和方式還是大同小異的。尤其是在picasso也吸收了glide中一些優良的方法,差異越來越小。所以只在載入圖片這個模組中,其實差異不大,要根據自己專案需求來選擇哪個框架。要相信,木有最好的框架,只有最適合的。閒話少說,開始講glide的使用方法,因為glide版本比較多。 目前使用的是4.7.1,所以下面的內容就以這個版本為準。 對於以前的3.x要遷移到4.x請參考
-
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。
-
總結
到這裡,基本把常用的方法都大致說了一下。後面會寫具體的分析。 如果有什麼遺漏或者不正確的地方,請不吝賜教,留下評論。