Glide是 Google推薦的圖片加載庫(kù),它可以支持來(lái)自u(píng)rl,Android資源,文件,Uri中的圖片加載,同時(shí)還支持gif圖片的加載,以及各種圖片顯示前的bitmap處理(例如:圓角圖片,圓形圖片,高斯模糊,旋轉(zhuǎn),灰度等等),緩存處理,請(qǐng)求優(yōu)先級(jí)處理,動(dòng)畫處理,縮略圖處理,圖片大小自定義等等.可謂是非常的強(qiáng)大.
需要在build.gradle中加入依賴,目前最新的版本是3.7.0,Glide庫(kù)地址
compile 'com.github.bumptech.glide:glide:3.7.0'1Created by YWH on2017/2/9
. */public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.drawable.test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); Glide.with(this). load(uri). asBitmap(). into(targetView); }}12345678910111213141516效果圖:
另外,crossFade還可以接收一個(gè)參數(shù)來(lái)設(shè)置淡入顯示效果的持續(xù)時(shí)間,crossFade(int duration); 如果你想直接顯示圖片,而不是淡入顯示圖片,則可以通過(guò)dontAnimate()方法設(shè)置.
CenterCrop,FitCenter都是對(duì)目標(biāo)圖片進(jìn)行裁剪,了解過(guò)ImageView的ScaleType屬性就知道,這2種裁剪方式在ImageView上也是有的,分別對(duì)應(yīng)ImageView的ImageView.ScaleType.CENTER_CROP和mageView.ScaleType.FIT_CENTER的.
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); targetView.setScaleType(ImageView.ScaleType.FIT_CENTER); Glide.with(this). load(R.drawable.test). placeholder(R.drawable.bg_loading).//加載中顯示的圖片 error(R.drawable.bg_error).//加載失敗時(shí)顯示的圖片 crossFade(1000).//淡入淡出,注意:如果設(shè)置了這個(gè),則必須要去掉asBitmap override(80,80).//設(shè)置最終顯示的圖片像素為80*80,注意:這個(gè)是像素,而不是控件的寬高 centerCrop().//中心裁剪,縮放填充至整個(gè)ImageView into(targetView); }}12345678910111213141516171819內(nèi)存緩存設(shè)置,通過(guò)skipMemoryCache(boolean)來(lái)設(shè)置是否需要緩存到內(nèi)存,默認(rèn)是會(huì)緩存到內(nèi)存的.
/** * Created by YWH on2017/2/9 */public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); targetView.setScaleType(ImageView.ScaleType.FIT_CENTER); Glide.with(this). load(R.drawable.test). placeholder(R.drawable.bg_loading).//加載中顯示的圖片 error(R.drawable.bg_error).//加載失敗時(shí)顯示的圖片 crossFade(1000).//淡入淡出,注意:如果設(shè)置了這個(gè),則必須要去掉asBitmap override(80,80).//設(shè)置最終顯示的圖片像素為80*80,注意:這個(gè)是像素,而不是控件的寬高 centerCrop().//中心裁剪,縮放填充至整個(gè)ImageView skipMemoryCache(true).//跳過(guò)內(nèi)存緩存 into(targetView); }}123456789101112131415161718192021磁盤緩存,磁盤緩存通過(guò)diskCacheStrategy(DiskCacheStrategy)來(lái)設(shè)置,DiskCacheStrategy一共有4種模式:
DiskCacheStrategy.NONE:什么都不緩存 DiskCacheStrategy.SOURCE:僅緩存原圖(全分辨率的圖片)DiskCacheStrategy.RESULT:僅緩存最終的圖片,即修改了尺寸或者轉(zhuǎn)換后的圖片DiskCacheStrategy.ALL:緩存所有版本的圖片,默認(rèn)模式public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); targetView.setScaleType(ImageView.ScaleType.FIT_CENTER); Glide.with(this). load(R.drawable.test). placeholder(R.drawable.bg_loading).//加載中顯示的圖片 error(R.drawable.bg_error).//加載失敗時(shí)顯示的圖片 crossFade(1000).//淡入淡出,注意:如果設(shè)置了這個(gè),則必須要去掉asBitmap override(80, 80).//設(shè)置最終顯示的圖片像素為80*80,注意:這個(gè)是像素,而不是控件的寬高 centerCrop().//中心裁剪,縮放填充至整個(gè)ImageView skipMemoryCache(true).//跳過(guò)內(nèi)存緩存 diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最終圖片 into(targetView); }}1234567891011121314151617181920在GlideModule 中,我們可以設(shè)置磁盤緩存的位置,磁盤緩存的大小和內(nèi)存緩存的大小,同時(shí)還可以設(shè)置圖片的顯示質(zhì)量.
要是用GlideModule ,需要?jiǎng)?chuàng)建它的實(shí)現(xiàn)類,然后在manifests中申明實(shí)現(xiàn)類的全類路徑:
<meta-data android:name="com.example.mchenys.httputilsdemo.image.glide.module.SimpleGlideModule" android:value="GlideModule" />123GlideModule 的實(shí)現(xiàn)類,需要實(shí)現(xiàn)applyOptions方法:
/** * 所以你知道要?jiǎng)?chuàng)建一個(gè)額外的類去定制 Glide。 * 下一步是要全局的去聲明這個(gè)類,讓 Glide 知道它應(yīng)該在哪里被加載和使用。 * Glide 會(huì)掃描 AndroidManifest.xml 為 Glide module 的 meta 聲明。 * 因此,你必須在 AndroidManifest.xml 的 <application> 標(biāo)簽內(nèi)去聲明這個(gè)SimpleGlideModule。 * Created by YWH on2017/2/9 */public class SimpleGlideModule implements GlideModule { public static DiskCache cache; @Override public void applyOptions(Context context, GlideBuilder builder) { // 在 Android 中有兩個(gè)主要的方法對(duì)圖片進(jìn)行解碼:ARGB8888 和 RGB565。前者為每個(gè)像素使用了 4 個(gè)字節(jié), // 后者僅為每個(gè)像素使用了 2 個(gè)字節(jié)。ARGB8888 的優(yōu)勢(shì)是圖像質(zhì)量更高以及能存儲(chǔ)一個(gè) alpha 通道。 // Picasso 使用 ARGB8888,Glide 默認(rèn)使用低質(zhì)量的 RGB565。 // 對(duì)于 Glide 使用者來(lái)說(shuō):你使用 Glide module 方法去改變解碼規(guī)則。 builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); //設(shè)置緩存目錄 File cacheDir = PathUtils.getDiskCacheDir(context, CacheConfig.IMG_DIR); cache = DiskLruCacheWrapper.get(cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);// 250 MB builder.setDiskCache(new DiskCache.Factory() { @Override public DiskCache build() { return cache; } }); //設(shè)置memory和Bitmap池的大小 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); builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize)); builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize)); } @Override public void registerComponents(Context context, Glide glide) { }}12345678910111213141516171819202122232425262728293031323334353637383940414243Glide 可以用 Priority 枚舉來(lái)設(shè)置圖片的加載優(yōu)先級(jí),這樣我們就可以針對(duì)那些需要顯示的圖片設(shè)置高的優(yōu)先級(jí)了. Priority 有4種級(jí)別: Priority.LOW Priority.NORMAL Priority.HIGH Priority.IMMEDIATE 例如:
/** * 高優(yōu)先級(jí)加載 * @param url * @param imageView * @param listener */ public static void loadImageWithHighPriority(Object url,ImageView imageView, final LoaderListener listener) { if (url == null) { if (listener != null) { listener.onError(); } } else { Glide.with(imageView.getContext()). load(url). asBitmap(). priority(Priority.HIGH).//高優(yōu)先級(jí) dontAnimate(). listener(new RequestListener<Object, Bitmap>() { @Override public boolean onException(Exception e, Object model, Target<Bitmap> target, boolean isFirstResource) { if (null != listener) { listener.onError(); } return false; } @Override public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) { if (null != listener) { listener.onSuccess(); } return false; } }).into(imageView); } }123456789101112131415161718192021222324252627282930313233343536通過(guò)設(shè)置縮略圖,我們可以在顯示目標(biāo)圖片之前先展示一個(gè)第分辨率或者其他圖片,當(dāng)全分辨率的目標(biāo)圖片在后臺(tái)加載完成后, Glide會(huì)自動(dòng)切換顯示全像素的目標(biāo)圖片.
設(shè)置縮略圖有2種方式: 通過(guò)thumbnail(float)指定0.0f~1.0f的原始圖像大小,例如全像素的大小是500*500,如果設(shè)置為thumbnail為0.1f,即目標(biāo)圖片的10%,顯示的縮略圖大小就是50*50;
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); Glide.with(this). load(R.drawable.test). placeholder(R.drawable.bg_loading).//加載中顯示的圖片 error(R.drawable.bg_error).//加載失敗時(shí)顯示的圖片 crossFade(1000).//淡入淡出,注意:如果設(shè)置了這個(gè),則必須要去掉asBitmap override(80, 80).//設(shè)置最終顯示的圖片像素為80*80,注意:這個(gè)是像素,而不是控件的寬高 centerCrop().//中心裁剪,縮放填充至整個(gè)ImageView skipMemoryCache(true).//跳過(guò)內(nèi)存緩存 diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最終圖片 thumbnail(0.1f).//10%的原圖大小 into(targetView); }}123456789101112131415161718192021通過(guò)thumbnail(DrawableRequestBuilder)方式來(lái)指定縮略圖,該縮略圖可以使用load的所有方式(網(wǎng)絡(luò),文件,uri,資源)加載.
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); //縮略圖請(qǐng)求 DrawableRequestBuilder<String> thumbnailRequest = Glide .with(this) .load("http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png"); Glide.with(this). load(R.drawable.test).// placeholder(R.drawable.bg_loading).//加載中顯示的圖片// error(R.drawable.bg_error).//加載失敗時(shí)顯示的圖片// crossFade(1000).//淡入淡出,注意:如果設(shè)置了這個(gè),則必須要去掉asBitmap override(80, 80).//設(shè)置最終顯示的圖片像素為80*80,注意:這個(gè)是像素,而不是控件的寬高 centerCrop().//中心裁剪,縮放填充至整個(gè)ImageView skipMemoryCache(true).//跳過(guò)內(nèi)存緩存 diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最終圖片 thumbnail(thumbnailRequest).//設(shè)置縮略圖 into(targetView); }}12345678910111213141516171819202122232425在顯示目標(biāo)圖片之前,我們可以對(duì)目標(biāo)圖片的Bitmap進(jìn)行相應(yīng)的處理,例如::圓角圖片,圓形圖片,高斯模糊,旋轉(zhuǎn),灰度等等. 只需要實(shí)現(xiàn)Transformation接口即可,該接口的transform方法會(huì)返回顯示圖片前的Bitmap對(duì)象,在該方法中對(duì) Bitmap的任何處理,都會(huì)影響到最終的顯示結(jié)果. 當(dāng)然,如果你只是想要對(duì)圖片做常規(guī)的 bitmap 轉(zhuǎn)換,你可以繼承抽象類BitmapTransformation,它簡(jiǎn)化了Transformation接口的實(shí)現(xiàn),這應(yīng)該能覆蓋大部分的應(yīng)用場(chǎng)景了。
使用的時(shí)候,通過(guò)transform(Transformation… transformations)來(lái)設(shè)置.例如:
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); Glide.with(this). load(R.drawable.test). asBitmap(). transform(new BlurTransformation(this)).//高斯模糊處理 into(targetView); }}12345678910111213下面貼出常用的幾個(gè)Bitmap的轉(zhuǎn)換處理的代碼,在github上也有g(shù)lide-transformations-master庫(kù).
網(wǎng)上提供的FastBlur,可兼容低版本的高斯模糊處理
public class FastBlur { public static Bitmap blur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { Bitmap bitmap; if (canReuseInBitmap) { bitmap = sentBitmap; } else { bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); } if (radius < 1) { return (null); } int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w * h]; bitmap.getPixels(pix, 0, w, 0, 0, w, h); int wm = w - 1; int hm = h - 1; int wh = w * h; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; int vmin[] = new int[Math.max(w, h)]; int divsum = (div + 1) >> 1; divsum *= divsum; int dv[] = new int[256 * divsum]; for (i = 0; i < 256 * divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; int[][] stack = new int[div][3]; int stackpointer; int stackstart; int[] sir; int rbs; int r1 = radius + 1; int routsum, goutsum, boutsum; int rinsum, ginsum, binsum; for (y = 0; y < h; y++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; for (i = -radius; i <= radius; i++) { p = pix[yi + Math.min(wm, Math.max(i, 0))]; sir = stack[i + radius]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rbs = r1 - Math.abs(i); rsum += sir[0] * rbs; gsum += sir[1] * rbs; bsum += sir[2] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } } stackpointer = radius; for (x = 0; x < w; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (y == 0) { vmin[x] = Math.min(x + radius + 1, wm); } p = pix[yw + vmin[x]]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[(stackpointer) % div]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi++; } yw += w; } for (x = 0; x < w; x++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; yp = -radius * w; for (i = -radius; i <= radius; i++) { yi = Math.max(0, yp) + x; sir = stack[i + radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; rbs = r1 - Math.abs(i); rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } if (i < hm) { yp += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; y++) { // Preserve alpha channel: ( 0xff000000 & pix[yi] ) pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (x == 0) { vmin[y] = Math.min(y + r1, hm) * w; } p = x + vmin[y]; sir[0] = r[p]; sir[1] = g[p]; sir[2] = b[p]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[stackpointer]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi += w; } } bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209android4.3之后可使用,需要在build.gradle中配置:
defaultConfig { //BlurTransformation renderscriptTargetApi 23 renderscriptSupportModeEnabled true}123456通過(guò)animate()方法可以設(shè)置xml文件定義的4種補(bǔ)間動(dòng)畫(alpha、scale、translate、rotate) 例如:
res/anim/left_in.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="@android:integer/config_mediumAnimTime" android:fromXDelta="-50%p" android:toXDelta="0"/> <alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="0.0" android:toAlpha="1.0"/></set>123456789101112使用方式:
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); Glide.with(this). load(R.drawable.test). asBitmap(). animate(R.anim.left_in).//加載xml文件定義的動(dòng)畫 into(targetView); }}12345678910111213處理此外,還可以通過(guò)animate指定屬性動(dòng)畫:
public class TestGlideActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); ImageView targetView = (ImageView) findViewById(R.id.iv_target); ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() { @Override public void animate(View view) { //設(shè)置屬性動(dòng)畫 ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationX", -500f, 0f); ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f); ObjectAnimator moveTop = ObjectAnimator.ofFloat(view, "translationY", 0f, -2000, 0f); AnimatorSet animSet = new AnimatorSet(); //先左進(jìn),然后旋轉(zhuǎn)伴隨淡入效果,最后移動(dòng)向上 animSet.play(rotate).with(fadeInOut).after(moveIn).before(moveTop); animSet.setDuration(5000); animSet.start(); } }; Glide.with(this). load(R.drawable.test). asBitmap(). animate(animationObject).//加載屬性動(dòng)畫 into(targetView); }}1234567891011121314151617181920212223242526272829
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注