Glide簡介
An image loading and caching library for Android focused on smooth scrolling
一個專注於流暢滑動的圖片載入和快取庫
優勢
其實現在,圖片載入和快取的庫已經超級多了,Glide
是目前谷歌官方推薦的載入庫,它有一個比較牛的特點就是支援GIF格式的圖片播放,目前的人氣也超級高!!另外還可以設定漸變的載入效果,控制相關快取策略等!以下就圍繞這些做一些具體的介紹!
引入庫
1 2 3 4 5 6 7 8 |
repositories { mavenCentral() // jcenter() works as well because it pulls from Maven Central } dependencies { compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.android.support:support-v4:19.1.0' } |
如果你的網路請求底層使用了Okhttp
的話,那麼可以指定這個讓Glide
網路層使用Okhttp
。
1 2 3 4 5 6 7 8 9 |
dependencies { compile 'com.github.bumptech.glide:okhttp-integration:1.4.0@aar' //compile 'com.squareup.okhttp:okhttp:2.2.0' } dependencies { compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' //compile 'com.squareup.okhttp3:okhttp:3.2.0' } |
AndroidManifest
裡面加入相關的配置:
1 2 3 |
<meta-data android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule" android:value="GlideModule" /> |
基本的載入
1 2 3 |
Glide.with(image.getContext()) .load(imageUrl) .into(image); |
.crossFade()
來指定一個漸變的效果:
1 2 3 4 5 6 |
Glide.with(image.getContext()) .load(imageUrl) .error(R.mipmap.girl) .placeholder(R.mipmap.ic_launcher) .crossFade(R.anim.fade_out_rapidly, 5000) .into(image); |
一般使用到這這裡就差不多了吧,不過要是覺得Glide就這樣了那可真的是太對不住Glide了!
進階-快取策略:
Glide
預設會使用磁碟快取和記憶體快取的,你可以根據喜好和相關的使用場景定製相關的策略。
skipMemoryCache()
跳過記憶體快取,這個預設就是false。如果不需要就設定為true來確保不會快取到記憶體中。
diskCacheStrategy()
磁碟快取策略,Glide
支援很多種圖片快取策略。
DiskCacheStrategy.RESOURCE
只快取原始檔案
DiskCacheStrategy.ALL
快取所有size的圖片和原始檔
DiskCacheStrategy.RESULT
快取最後的結果檔案
DiskCacheStrategy.NONE
撒都不快取
在V3的版本預設是DiskCacheStrategy.RESULT
的策略。
進階-轉換
1 2 |
asBitmap() //總是將其轉換為Bitmap的物件 asGif() //總是將其轉換為gi的物件,但是如果它不是gif的,那麼就會轉換失敗,所以最好要設定一個error()的物件 |
另外Glide提供了相關的方法,你可以自定義相關的 Transformation
,來完成相關的轉換!
這裡一共有兩個方法,一個是transform()
,一個是getId()
,如果說我們需要完成一些自己的需求,比如說,你需要載入出圓形的圖片,這裡簡單有效的方法就是直接設定一個CirCleTransform
就好了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
public class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); } 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.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | Paint .ANTI_ALIAS_FLAG); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader .TileMode.CLAMP)); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return result; } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } @Override public String getId() { return getClass().getName(); } } |
如果需要圓角矩形的話:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public class RoundTransform extends BitmapTransformation { private int cornerRadius; private RectF rectF = new RectF(); /** * @param round dp */ public RoundTransform(Context context,int round) { super(context); float density = context.getResources().getDisplayMetrics().density; this.cornerRadius = (int) (round/density+0.5f); } private Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int width = source.getWidth(); int height = source.getHeight(); rectF.set(0, 0, width, height); Bitmap squared = Bitmap.createBitmap(source, 0, 0, width, height); Bitmap result = pool.get(width, height, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | Paint .ANTI_ALIAS_FLAG); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader .TileMode.CLAMP)); canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint); return result; } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } @Override public String getId() { return getClass().getName(); } } |
Glide還為我們提供了CenterCrop
FitCenter
等轉換器,這些我們都可以直接使用!
這裡的getId()返回的必須是唯一的字串
說白了,我們這裡可以做很多的操作的,因為我們已經拿到相關的物件,可以隨意的進行各種旋轉、平移、放大、高斯模糊等。
Glide 轉換集合 已經給我們儘可能提過了足夠的轉換!
所以,還去引入什麼CircleImageView
什麼的,真的就可以考慮考慮了,簡直弱爆了!一個Transform
直接搞定。
進階-相關回撥
1 2 3 4 5 6 7 8 9 10 |
RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { return false; } |
onResourceReady()
當資源載入成功之後,會走這個回撥。
onException()
當載入異常時,會走這個回撥。
進階-各種Target
1 2 3 |
Glide.with(getApplicationContext()) .load(imageUrl) .into(mTarget); |
如果需要給自定義View載入對應的圖片,因為Glide
根本不知道圖片需要載入到那個具體的View上面去展示,那這個就需要使用Glide
為我們提供的相關介面,自己去實現就好了。
比如我們這裡有一個自定義的FrameLayout
,名字就叫MyFrameLayout
,裡面有一個TextView
和一個ImageView
,
對外提供一個方法:
1 2 3 |
public void setimage(Drawable current) { imageView.setBackground(current); } |
然後自定義一個ViewTarget:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class MyViewTarget extends ViewTarget<MyFrameLayout, GlideDrawable> { public MyViewTarget(MyFrameLayout view) { super(view); } @Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { this.view.setImage(resource.getCurrent()); } } `Glide`已經針對一些特殊情況制定了一些適合的Target,比如說通知欄相關的建立,`NotificationTarget`這些我們都可以直接獲取使用。 |
進階-定製各種策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
我們可以通過GlideMode來定製相關的策略,比如說磁碟快取,記憶體快取,載入圖片使用的編碼等! public class GlideConfiguration implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { // Prefer higher quality images unless we're on a low RAM device MemorySizeCalculator calculator = new MemorySizeCalculator(context); int defaultMemoryCacheSize = calculator.getMemoryCacheSize(); int defaultBitmapPoolSize = calculator.getBitmapPoolSize(); int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize); int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize); //1、記憶體快取相關 builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize)); builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize)); // set size & external vs. internal int cacheSize100MegaBytes = 104857600; //2、磁碟快取相關 builder.setDiskCache( // new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)//內部使用的磁碟快取區 new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)//外部可以訪問的磁碟快取區 ); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); //3、根據執行記憶體情況,自定義對影象的編碼格式 builder.setDecodeFormat(activityManager.isLowRamDevice() ? DecodeFormat.PREFER_RGB_565 : DecodeFormat.PREFER_ARGB_8888); } @Override public void registerComponents(Context context, Glide glide) { } } |
記得要在AndroidManifiest
裡面配置相關的引數:
1 2 3 |
<meta-data android:name="io.plaidapp.util.glide.GlideConfiguration" android:value="GlideModule" /> |
總結
青出於藍勝於藍,Glide就是在Picasso的基礎上改進出來的,有著相似的呼叫方法!作為新秀,增加的Gif的支援可以說是它的新的優勢!豐富的快取策略也更能滿足開發需求。
要看Glide運用專案的話,推薦Plaid,保證你有收穫!
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式