在Android開發中,圖片加載已經是必不可少的一部分,無論是新聞類App,購物類、社交類等等,已經不可能不涉及到圖片加載。現在的圖片加載框架也是很多,我們最熟悉的應該是UIL了,今天就來記錄一下Glide的使用。
老規矩,在節目開始之前,我們先來一個搞笑段子:
雖然我不會賺錢,但是我會省錢啊。我早上就看上一輛蘭博基尼,我一咬牙、一跺腳,不買!!
一下子就省了七百多萬。。
1、當前比較好的圖片加載框架
Universal Image Loader:使用最廣,很強大,但現在官方已停止維護。
Picasso:和Glide非常像,Square開發的牛逼框架。
Volley:Google官方出品。
Fresco:FaceBook出品,數據相當厲害。
Glide:今天的主角,官方推薦,專注於界面流暢的滾動。
2、簡介
創建Glide的主要目的有兩個,一個是實現平滑的圖片列表滾動效果,另一個是支持遠程圖片的獲取、大小調整和展示。它還可以加載Gif動態圖,後面再說。
3、jar包
https://github.com/bumptech/glide/releases
https://github.com/bumptech/glide/wiki
4、Gradle編譯
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:support-v4:22.0.0'
}
5、基本使用
Glide.with(context)
.load("xxxx.png")
.into(imageView);
Glide的代碼設計採用現在流行的“流式代碼”,方法調用都是一路點點點調用,這個好處就是調用邏輯非常清晰,無論以後某個具體的實現怎麼變化,整體的流程都非常清晰,一目瞭然。
下面分別解釋三個函數
6、Glide的with()可以接受的類型有如下:
Context context;
Activity activity;
FragmentActivity fragmentActivity;
Fragment fragment;
相比Picasso只能接受Context要稍微好一點。
7、load()是加載目標資源,可以接受的參數類型有如下:
Uri uri;
String uriString;
File file;
Integer resourceId;
byte[] model;
String model;
這麼多種加載方式,是不是很方便。
8、into()就是加載資源完成後作什麼處理,它接受三種參數:
1)into(ImageView imageView);//顯示在控件上。
Glide.with(context)
.load("xxxx.png")
.into(imageView);
2)into(Target target);//通過回調獲得加載結果。
Glide.with(context)
.load(url)
.into(new SimpleTarget<Bitmap>(width, height) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
}
};
3)into(int w, int h);//指定期望的圖片大小,返回一個future對象,要在子線程中獲取。
new Thread(new Runnable() {
@Override
public void run() {
Bitmap bitmap = Glide.with(context)
.load("xxxx.png")
.into(200, 200)
.get();
}
}).start();
into的三種用法區別是什麼呢?
第一種是直接把圖片加載出來顯示在ImageView上,你並不會得到中間結果,也就是bitmap對象。
第二種、第三種都是可以獲取到bitmap的,獲取到後怎麼處理自己決定。
第三種需要在子線程中調用。
除了with(),load(),into()三個基本的方法,Glide還有很多使用的Api。
9、設置圖片大小
.override(int w, int h);
指定加載bitmap的大小,比如原圖是500 x 500,into(100, 100),加載出的bitmap就是100 x 100。
10、加載完成動畫
.animate(Animator animator);//或者int animationId
初次加載出Bitmap時展示的動畫,可以是屬性動畫,也可以是Tween動畫。
**注意:這個動畫只在初次加載出來時使用,已經加載過了,下載再從緩存中取是不會動畫的。
11、裁剪策略
.centerCrop()
裁剪,相當於ImageView設置scaleType爲centerCrop,大圖的裁剪策略。
12、佔位和錯誤顯示
.placeHolder(int resourceId);
.error(int resourceId);
加載時和加載過程中顯示的圖片,這個圖片通常就是本地的一張資源圖片,因爲它本身就是爲了解決加載網絡圖延遲的手段,自己如果還要從網絡獲取就不合適了。
13、緩存策略
.diskCacheStrategy(DiskCacheStrategy.ALL)
這個是設置緩存策略。
DiskCacheStrategy.NONE:不緩存
DiskCacheStrategy.SOURCE:緩存原始圖片
DiskCacheStrategy.RESULT:緩存壓縮過的結果圖片
DiskCacheStrategy.ALL:兩個都緩存
14、加載gif動態圖
.asBitmap()
.asGif()
只需要加一行代碼,Glide就可以直接在ImageView上加載gif動態圖,這個還是很方便的。
Glide.with(context)
.load("xxx.gif")
.asGif()
.into(imageView);
關鍵就是asGif()這行代碼,它就會自動加載成gif動態圖,如果改成asBitmap(),就是靜態圖。
15、圖片轉換transform
.tranform(Tranformation tranformation)
Tranformation:轉換,用於對bitmap進行轉換。
官方解釋:所設置的轉換方式會應用在每一幀圖片或者是gif圖片的每一個bitmap
比如我們要用Glide加載出圓角圖片,或者是圓形圖片,就要用到Transformation。
具體的方法就是寫一個類繼承BitmapTransformation,然後重寫transform()方法。
<圓角圖片>
public class GlideRoundTransform extends BitmapTransformation {
public static final int DEFAULT_CORNER_RADIO = 10;
private static float radius = 0f;
public GlideRoundTransform(Context context) {
this(context, DEFAULT_CORNER_RADIO);
}
public GlideRoundTransform(Context context, int dp) {
super(context);
this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
}
@Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
private static 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);
}
}
<圓形圖片>
public class GlideCircleTransform extends BitmapTransformation {
public GlideCircleTransform(Context context) {
super(context);
}
@Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
// TODO this could be acquired from the pool too
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);
return result;
}
@Override public String getId() {
return getClass().getName();
}
}
16、移除當前Transformation
.dontTransform()
17、移除所有的動畫
.dontAnimate()
18、跳過內存緩存
.skipMemoryCache(true)
19、色彩模式
Glide 在默認的 RGB_565 格式下加載的圖片質量可以接受的話,可以什麼都不做。但如果你覺得難以接受,或者是你的實際需求對圖片的質量有更高的要求的話,你可以像下面的代碼那樣創建一個 GlideModule 子類,把 Bitmap 的格式轉換到 ARGB_8888:
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) {
}
}
//manifest
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration" android:value="GlideModule"/>
20、暫停\回覆請求
Glide.with(context).resumeRequests();
Glide.with(context).pauseRequests();
當列表在滑動的時候,調用pauseRequests()取消請求,滑動停止時,調用resumeRequests()恢復請求。
21、清空請求列表
Glide.clear()
22、下載圖片,並且獲取下載路徑
new Thread(new Runnable() {
@Override
public void run() {
try {
Future<File> fu = Glide.with(MainActivity.this)
.load("https://www.baidu.com/img/bdlogo.png")
.downloadOnly(200, 200);
File file = file;
Log.e("TAG", "## path=" + file.getAbsoluteFile());
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[fis.available()];
fis.read(data, 0, fis.available());
fis.close();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//do something...
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
注意:必須是在子線程中使用
哎呦,差不多了,寫的好累。基本的用法就這些。以後還有新的我再更新,希望能對正在學習Glide的朋友起到點作用。
本期節目就到這裏,感謝大家的收看,我們下期再見!