前言
一般項目我都會使用Glide作為我的圖片加載框架蝇刀,他和Picasso ,真的很像树枫,郭大神早就分析過了直焙,很詳細,這里也就簡單做個記錄砂轻。小白白一枚奔誓,學(xué)習(xí)路上
Android圖片加載框架最全解析(一),Glide的基本用法
Android圖片加載框架最全解析(二)搔涝,從源碼的角度理解Glide的執(zhí)行流程
Android圖片加載框架最全解析(三)厨喂,深入探究Glide的緩存機制
Android圖片加載框架最全解析(四),玩轉(zhuǎn)Glide的回調(diào)與監(jiān)聽
Android圖片加載框架最全解析(五)庄呈,Glide強大的圖片變換功能
Android圖片加載框架最全解析(六)蜕煌,探究Glide的自定義模塊功能
Android圖片加載框架最全解析(七),實現(xiàn)帶進度的Glide圖片加載功能
Android圖片加載框架最全解析(八)诬留,帶你全面了解Glide 4的用法
目錄
- 一:GitHub
- 二:下載使用
- Gradle
-
- Android SDK 要求
- 解決方案
- 3.權(quán)限
- 二:apply && RequestOptions
- 三:API 介紹
- 四: 補充說明
- diskCacheStrategy參數(shù)補充
- asBitmap()注意坑
- submit()
-
- transforms
- (1) 轉(zhuǎn)成黑白
- (2) 高斯模糊
- (3) 圓形
- (4 ) 圓角
- 5.Generated API
一:GitHub
bumptech/glide
二:下載使用
點擊斜纪,跳轉(zhuǎn)到官網(wǎng)贫母,介紹很詳細
1. Gradle
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}
dependencies {
compile 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
}
2. Android SDK 要求
- Min Sdk Version - 使用 Glide 需要 min SDK 版本 API 14 (Ice Cream Sandwich) 或更高。
- Compile Sdk Version - Glide 必須使用 API 26 (Oreo) 或更高版本的 SDK 來編譯盒刚。
- Support Library Version - Glide 使用的支持庫版本為 27腺劣。
否則會出現(xiàn)如下異常
解決方案
dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2' //這個版本的就可以了
implementation 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
}
3.權(quán)限
<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" />
二:apply && RequestOptions
4.0之前最常用的方式,當(dāng)然現(xiàn)在也是哈
Glide.with(this)
.load(url)
.into(img);
4.0之后伪冰,有一個新的東西
Glide.with(this)
.load(url)
// .apply(RequestOptions options)
.into(img);
比如 我們加載占位圖和錯誤圖
RequestOptions options = new RequestOptions()
.error(R.drawable.error)
.placeholder(R.drawable.loading);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
小伙伴們沒看錯誓酒,這樣的方式,擺脫了贮聂,以前鏈?zhǔn)綄懛ㄖ锌扛蹋珿lide很長很長,現(xiàn)在的話吓懈,我們可以傳入一個RequestOptions歼冰,對象,就有小伙伴問了耻警,有啥用隔嫡,我覺得,比較容易封裝甘穿,
例如
public class GlideUtil {
public static void load(Context context,
String url,
ImageView imageView,
RequestOptions options) {
Glide.with(context)
.load(url)
.apply(options)
.into(imageView);
}
}
三:API 介紹
API | 介紹 |
---|---|
占位符(Placeholder) | 當(dāng)請求正在執(zhí)行時被展示的 Drawable |
錯誤符(Error) | 請求永久性失敗時展示 |
后備回調(diào)符(Fallback) | 在請求的url/model為 null 時展示 |
override | 指定了一個圖片的尺寸,Target.SIZE_ORIGINAL 加載圖片的原始尺寸 |
skipMemoryCache(true) | 禁用內(nèi)存緩存功能 |
diskCacheStrategy(DiskCacheStrategy.NONE) | 禁用硬盤緩存功能,參數(shù)列表如下 四(1) |
asBitmap() | 只允許加載靜態(tài)圖片,腮恩。如果傳入的是GIF圖,會展示GIF圖的第一幀 |
asFile() | 指定文件格式 注意事項 如下 四(2) |
asDrawable() | 指定Drawable格式 |
submit() | 使用如下四(3) |
transforms | 圖片變換,Glide 默認有3個温兼,如下四(4) |
四: 補充說明
1. diskCacheStrategy參數(shù)補充
參數(shù) | 說明 |
---|---|
DiskCacheStrategy.NONE | 表示不緩存任何內(nèi)容秸滴。 |
DiskCacheStrategy.DATA | 表示只緩存原始圖片。 |
DiskCacheStrategy.RESOURCE | 表示只緩存轉(zhuǎn)換過后的圖片募判。 |
DiskCacheStrategy.ALL | 表示既緩存原始圖片荡含,也緩存轉(zhuǎn)換過后的圖片。 |
DiskCacheStrategy.AUTOMATIC | 表示讓Glide根據(jù)圖片資源智能地選擇使用哪一種緩存策略(默認選項)届垫。 |
2. asBitmap()注意坑
熟悉Glide 3的朋友對asBitmap()方法肯定不會陌生對吧释液?但是千萬不要覺得這里就沒有陷阱了,在Glide 3中的語法是先load()再asBitmap()的装处,而在Glide 4中是先asBitmap()再load()的误债。乍一看可能分辨不出來有什么區(qū)別,但如果你寫錯了順序就肯定會報錯了
3. submit()
通過如下代碼妄迁,可以獲取到找前,下載好的圖片放在哪,可以看到 都在cache
下
new Thread(new Runnable() {
@Override
public void run() {
try {
File file = Glide.with(MainActivity.this)
.asFile()
.load(url)
.submit()
.get();
Log.e("Tag", "path-->" + file.getPath());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
E/Tag: path-->/data/user/0/com.allens.glidedemo/cache/image_manager_disk_cache/309df01e6362ddc8939a4e3c549e8276dffb0446a89f2facee371909301fe76a.0
4. transforms
內(nèi)置有這3個
RequestOptions options = new RequestOptions()
.centerCrop();
RequestOptions options = new RequestOptions()
.fitCenter();
RequestOptions options = new RequestOptions()
.circleCrop();//圓形
一般我們還會自己去定義判族,以下是常用的3種轉(zhuǎn)換
使用起來也很簡單
RequestOptions options = new RequestOptions()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE);
//圓形
.transforms(new CircleTransform(mContext,2, Color.DKGRAY))//外圈寬度躺盛,外圈顏色
//黑白
.transforms(new BlackWhiteTransformation());
//高斯模糊 范圍在 0 -- 25 越大模糊程度越高
.transforms(new BlurTransformation(mContext, 25)); // (0 < r <= 25)
//可以使用多種
.transforms(new BlurTransformation(mContext, 25),new CircleTransform(mContext,2, Color.DKGRAY))
(1) 轉(zhuǎn)成黑白
package com.allens.lib_glide.Transformation;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.support.annotation.NonNull;
import android.view.animation.Transformation;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.security.MessageDigest;
/**
* 描述:
* <p> 黑白
* Created by allens on 2018/1/8.
*/
public class BlackWhiteTransformation extends BitmapTransformation {
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return convertToBlackWhite(toTransform);
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
private Bitmap convertToBlackWhite(Bitmap bmp) {
int width = bmp.getWidth(); // 獲取位圖的寬
int height = bmp.getHeight(); // 獲取位圖的高
int[] pixels = new int[width * height]; // 通過位圖的大小創(chuàng)建像素點數(shù)組
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int alpha = 0xFF << 24;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int grey = pixels[width * i + j];
//分離三原色
int red = ((grey & 0x00FF0000) >> 16);
int green = ((grey & 0x0000FF00) >> 8);
int blue = (grey & 0x000000FF);
//轉(zhuǎn)化成灰度像素
grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
grey = alpha | (grey << 16) | (grey << 8) | grey;
pixels[width * i + j] = grey;
}
}
//新建圖片
Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
//設(shè)置圖片數(shù)據(jù)
newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
Bitmap resizeBmp = ThumbnailUtils.extractThumbnail(newBmp, 380, 460);
return resizeBmp;
}
}
(2)高斯模糊
package com.allens.lib_glide.Transformation;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSRuntimeException;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.security.MessageDigest;
/**
* 描述: 高斯模糊
* <p>
* Created by allens on 2018/1/8.
*/
public class BlurTransformation extends BitmapTransformation {
private Context context;
private float blurRadius;
public BlurTransformation(Context context, float blurRadius) {
this.context = context;
this.blurRadius = blurRadius;
}
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return blurBitmap(context, toTransform, blurRadius, outWidth, outHeight);
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
/**
* @param context 上下文對象
* @param image 需要模糊的圖片
* @param outWidth 輸入出的寬度
* @param outHeight 輸出的高度
* @return 模糊處理后的Bitmap
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public Bitmap blurBitmap(Context context, Bitmap image, float blurRadius, int outWidth, int outHeight) {
// 將縮小后的圖片做為預(yù)渲染的圖片
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, outWidth, outHeight, false);
// 創(chuàng)建一張渲染后的輸出圖片
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// 創(chuàng)建RenderScript內(nèi)核對象
RenderScript rs = RenderScript.create(context);
// 創(chuàng)建一個模糊效果的RenderScript的工具對象
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// 由于RenderScript并沒有使用VM來分配內(nèi)存,所以需要使用Allocation類來創(chuàng)建和分配內(nèi)存空間
// 創(chuàng)建Allocation對象的時候其實內(nèi)存是空的,需要使用copyTo()將數(shù)據(jù)填充進去
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
// 設(shè)置渲染的模糊程度, 25f是最大模糊度
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
blurScript.setRadius(blurRadius);
}
// 設(shè)置blurScript對象的輸入內(nèi)存
blurScript.setInput(tmpIn);
// 將輸出數(shù)據(jù)保存到輸出內(nèi)存中
blurScript.forEach(tmpOut);
// 將數(shù)據(jù)填充到Allocation中
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
(3) 圓形
package com.allens.lib_glide.Transformation;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.security.MessageDigest;
/**
* 描述:
* <p> 圓形
* Created by allens on 2018/1/8.
*/
public class CircleTransform extends BitmapTransformation {
private Paint mBorderPaint;
private float mBorderWidth;
public CircleTransform(Context context) {
super(context);
}
public CircleTransform(Context context, int borderWidth, int borderColor) {
super(context);
mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
mBorderPaint = new Paint();
mBorderPaint.setDither(true);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(borderColor);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
}
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2));
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
if (mBorderPaint != null) {
float borderRadius = r - mBorderWidth / 2;
canvas.drawCircle(r, r, borderRadius, mBorderPaint);
}
return result;
}
}
4.0 圓角
package com.starot.spark.transformation;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.security.MessageDigest;
/**
* 描述:
* <p> 圓形
*
* @author allens
* @date 2018/1/8
*/
public class CircleTransform extends BitmapTransformation {
private Paint mBorderPaint;
private float mBorderWidth;
public CircleTransform(Context context) {
super(context);
}
public CircleTransform(Context context, int borderWidth, int borderColor) {
super(context);
mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
mBorderPaint = new Paint();
mBorderPaint.setDither(true);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(borderColor);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
}
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2));
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
if (mBorderPaint != null) {
float borderRadius = r - mBorderWidth / 2;
canvas.drawCircle(r, r, borderRadius, mBorderPaint);
}
return result;
}
}
5.Generated API
如果4.0用的不爽,就想使用3.0版本的那種鏈?zhǔn)綄懛?將Glide 關(guān)鍵字改成
GlideApp即可
GlideApp.with(this)
.load(url)
.placeholder(R.drawable.loading)
.error(R.drawable.error)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(Target.SIZE_ORIGINAL)
.circleCrop()
.into(imageView);