使用Glide載入、快取圖片、Gif、解決背景出現淺綠色、GlideModules衝突
之前一直使用Volley ImageLoader、或者Picasso,無意間發現Glide,覺得真的是棒棒的。
1、和其他的一樣在Module的build.gradle中新增依賴
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:23.3.0'
都可以看到我不只是添加了一個依賴,還有V4包的依賴,因為它要藉助V4包工作。
2、Glide的使用和Picasso的使用十分相似都是.with().load.into()
Glide不僅可以載入網路的圖片,還可以加在本地的資源,檔案資源,最重要的是還可以加在GIF格式的圖片。
1)Glide載入網路圖片
Glide
.with(context)
.load("http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg")
.into(mImageView);
2)從資源中載入圖片
Glide
.with(context)
.load(R.mipmap.image)
.into(mImageView);
3)從檔案中載入
//這個檔案可能不存在於你的裝置中。然而你可以用任何檔案路徑,去指定一個圖片路徑。
File file = new File(Environment. getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "20160323153033.jpg");
Glide
.with(context)
.load(file)
.into(mImageView);
4)從Uri中載入
//這可能是任何 Uri為了演示的目的我們只是用一個 launcher icon 去建立了一個 Uri
Uri uri = resourceIdToUri(context, R.mipmap.image);
Glide
.with(context)
. load(uri)
.into(mImageView);
將id轉換成Uri
public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FOREWARD_SLASH = "/";
private static Uri resourceIdToUri(Context context, int resourceId) {
return Uri.parse(ANDROID_RESOURCE + context.getPackageName() + FOREWARD_SLASH + resourceId);
}
5)載入GIF圖片
載入gif圖片和載入正常的圖片沒有什麼太大的區別
String gifUrl = "http://pic.qqtn.com/file/2013/2014-12/2014122616202514075.gif";
Glide
.with( context )
.load( gifUrl )
.into( imageViewGif );
這裡我們可以稍做改動
//如果你期望這個 URL 是一個 Gif,Glide 不會自動檢查是否是 Gif,所以強制轉換
Glide.with( context ).load( gifUrl ).asGif().into( imageViewGif );
//顯示的是GIF動畫的第一幀,就是靜止的圖片
Glide.with( context ).load( gifUrl ).asBitmap().into( imageViewGif );
//1為GIF動畫載入的次數
Glide.with(MainActivity.this).load(fileGif).into(new GlideDrawableImageViewTarget(mImageView,1){
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
super.onResourceReady(resource, animation);
Log.e("---------->", "onResourceReady:載入完成");
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
Log.e("---------->", "onLoadFailed:" );
}
@Override
public void onLoadStarted(Drawable placeholder) {
super.onLoadStarted(placeholder);
Log.e("---------->", "onLoadStarted:" );
}
@Override
public void onStart() {
super.onStart();
Log.e("---------->", "onStart:" );
}
@Override
public void onStop() {
super.onStop();
Log.e("---------->", "onStop:" );
}
});
Glide GIF播放次數和監聽
3、圖片的載入會了,接下來看看如何設定圖片的大小
如果圖片不會自動適配到 ImageView,呼叫 override(horizontalSize, verticalSize) 。這將在圖片顯示到 ImageView之前重新改變圖片大小。
Glide
.with(context)
.load("http://p1.wmpic.me/article/2016/08/15/1471243206_FGLNjRtg_215x185.jpg")
.override(600, 200)
.into(mImageView);
4、影象的縮放
CenterCrop()是一個裁剪技術,即縮放影象讓它填充到 ImageView 界限內並且側鍵額外的部分。ImageView 可能會完全填充,但影象可能不會完整顯示。
Glide
.with(context)
.load(R.mipmap.image)
.centerCrop()
.into(imageViewResizeCenterCrop);
fitCenter() 是裁剪技術,即縮放影象讓影象都測量出來等於或小於 ImageView 的邊界範圍。該影象將會完全顯示,但可能不會填滿整個 ImageView。
Glide
.with(context)
.load(R.mipmap.image)
.fitCenter()
.into(imageViewResizeFitCenter);
5、縮圖
就是說我可以先載入圖片的百分之多少來顯示,然後在載入原圖,使用者體驗比較好嘿嘿
Glide
.with( context )
.load( "http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg" )
.thumbnail(0.1f)
.into(mImageView);
例如, 你傳了一個 0.1f 作為引數,Glide 將會顯示原始影象的10%的大小。如果原始影象有 1000x1000 畫素,那麼縮圖將會有 100x100 畫素。因為這個影象將會明顯比 ImageView 小很多,你需要確保它的 ScaleType 的設定是正確的。
6、我們通過網路得到的圖片有的時候不一定就直接設定到ImageView上,有的時候就只是要一個Bitmap
//當Glide載入完會被呼叫
private SimpleTarget target = new SimpleTarget<Bitmap>(){
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
//使用bitmap做一些事,如
mImageView.setImageBitmap(resource);
}
};
Glide
.with(this)
.load("http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg")
.asBitmap() //必須寫,否則會報型別轉化異常
.into(target); //此處為target
7、注意
如果看到這樣的異常You cannot start a load for a destroyed activity
請記住一句話:不要再非主執行緒裡面使用Glide載入圖片,如果真的使用了,請把context引數換成getApplicationContext。
8、Glide載入圖片背景出現淺綠色現象
- 原因:
Glide預設的Bitmap格式是RGB_565,這也是導致在載入圖片是可能變綠的罪魁禍首。RGB_565代表8位RGB點陣圖,而Picasso預設的Bitmap格式是ARGB_8888代表32位RGB點陣圖,點陣圖位數越高代表其可以儲存的顏色資訊越多,影象也就越逼真,這也是Picasso影象質量更好的原因了。
- 方案:
1、使用Glide載入圖片時:
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)//是將圖片原尺寸快取到本地。
.into(imageview);
2、如果加上這一句程式碼圖片仍然沒有解決,可以將Bitmap的格式改為ARGB_8888。
首先建立一個 GlideConfiguration類去實現GlideModule,修改Bitmap的格式。
public class GlideConfiguration implements GlideModule{
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
然後在AndroidManifest.xml中加入:
<meta-data
android:name="你的包名.GlideConfiguration"
android:value="GlideModule"/>
9、GlideModules衝突
雖然Glide允許一個應用當中存在多個GlideModules,Glide並不會按照一個特殊的順序去呼叫已註冊的GlideModules,如果一個應用的多個依賴工程當中有多個相同的Modules,就有可能會產生衝突。
如果一個衝突是不可避免的,應用應該預設去定義一個自己的Module,用來手動地處理這個衝突,在進行Manifest合併的時候,可以用下面的標籤排除衝突的module。
<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”remove”/>
1
10、Glide快取
Glide的快取功能設計成 二級快取:記憶體快取 & 硬碟快取
快取讀取順序:記憶體快取 –> 磁碟快取 –> 網路
記憶體快取 預設開啟
Glide中,記憶體快取 & 磁碟快取相互不影響,獨立配置
二級快取的作用不同:
記憶體快取:防止應用 重複將圖片資料 讀取到記憶體當中只快取轉換過後的圖片
硬碟快取:防止應用 重複從網路或其他地方重複下載和讀取資料
// 預設開啟記憶體快取,使用者不需要作任何設定
Glide.with(this)
.load(url)
.into(imageView);
// 可通過 API 禁用 記憶體快取功能
Glide.with(this)
.load(url)
.skipMemoryCache(true) // 禁用 記憶體快取
.into(imageView);
//可快取原始圖片 & 快取轉換過後的圖片,使用者自行設定
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
// 快取引數說明
// DiskCacheStrategy.NONE:不快取任何圖片,即禁用磁碟快取
// DiskCacheStrategy.ALL :快取原始圖片 & 轉換後的圖片
// DiskCacheStrategy.SOURCE:只快取原始圖片(原來的全解析度的影象,即不快取轉換後的圖片)
// DiskCacheStrategy.RESULT:(預設)只快取轉換後的圖片(即最終的影象:降低解析度後 / 或者轉換後 ,不快取原始圖片
下圖是自己遇到的坑,從Glide踩坑記中找到的答案
Glide踩坑記
Android原始碼分析:手把手帶你分析 Glide的快取功能
Glide詳解
一些常見問題
Glide載入監聽
Glide和自定義佈局(不是繼承ImageView)