第三方庫之—Glide的使用
Glide的使用
Glide是我使用最久,也是最喜歡的一款第三方圖片加載框架,以前只是使用,也沒有做系統性的總結,現在開始重新整理一遍這些優秀的第三方框架。
Glide官方地址:
Glide的相關方法:
- with:指定了聲明周期
- load():加載資源,String/Uri/File/Integer/URL/byte[]/T,或者 loadFromMediaStore(Uri uri)
- placeholder(resourceId/drawable): 設置資源加載過程中的占位Drawable。
- error():load失敗時顯示的Drawable。
- override() :調整圖片大小
- centerCrop():圖片裁剪,ImageView 可能會完全填充,但圖像可能不會完整顯示。
- fitCenter(): 圖像裁剪,圖像將會完全顯示,但可能不會填滿整個 ImageView。
- animate(): 指定加載動畫。
- crossFade()/crossFade(int duration):imageView改變時的動畫,version 3.6.1后默認開啟300毫秒
- dontAnimate():移除所有的動畫。
- transform():圖片轉換。
- bitmapTransform(): bitmap轉換,不可以和(centerCrop() 或 fitCenter())共用。
- priority(Priority priority):當前線程的優先級,Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL(default),Priority.LOW
- thumbnail(): 縮略圖.
- listener():異常監聽
- preload(int width, int height): 預加載resource到緩存中(單位為pixel)
- fallback(Drawable drawable):設置model為空時顯示的Drawable。
- using() :為單個的請求指定一個 model
- asGif():Gif 檢查,如果是圖片且加了判斷,則會顯示error占位圖,否則會顯示圖片
- asBitmap():bitmap轉化,如果是gif,則會顯示第一幀
- .skipMemoryCache(true) 禁止緩存
- .diskCacheStrategy(DiskCacheStrategy.NONE)禁止磁盤緩存
Glide 可以以load(File)的形式播放本地視頻,但是如果需要播放網絡視屏,則要用VideoView
緩存策略
一張圖片變化特別快的時候,應該禁止緩存.skipMemoryCache(true)
即使關閉內存緩存,請求圖片將會仍然被存儲在設備的磁盤緩存中,如果一張圖片變化很快,仍需要禁止磁盤緩存
.diskCacheStrategy(DiskCacheStrategy.NONE)
Glide 緩存了原始圖像,全分辨率圖像和另外小版本的圖像,因此禁用磁盤緩存是用枚舉來控制的
DiskCacheStrategy.NONE //什么都不緩存,就像剛討論的那樣
DiskCacheStrategy.SOURCE //僅僅只緩存原來的全分辨率的圖像。在我們上面的例子中,將會只有一個 1000x1000 像素的圖片
DiskCacheStrategy.RESULT //僅僅緩存最終的圖像,即,降低分辨率后的(或者是轉換后的)
DiskCacheStrategy.ALL //緩存所有版本的圖像(默認行為)
自定義緩存
磁盤緩存,用類DiskLruCacheWrapper來設置目錄builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
// 自己的緩存目錄
File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/package-name");
return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
}
});
內存緩存,用類Memory Cache 來設置大小
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
Bitmap Pool
重復使用及銷毀策略。設置方法:GlideBuilder.setBitmapPool() 默認采用的是LruBitmapPool,使用了LRU算法。MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
Bitmap Format
Bitmap Format用于設置全局缺省首選Bitmap規格,設置方法:GlideBuilder.setDecodeFormat() 默認采用RGB_565(比ARGB_8888節省一半的內存),但不支持透明度。優先級
會發現優先級高的先 顯示出來,即使圖片比較大。//優先加載
Glide
.with(context)
.load(heroImageUrl)
.priority(Priority.HIGH)
.into(imageViewHero);
//后加載
Glide
.with(context)
.load(itemImageUrl)
.priority(Priority.LOW)
.into(imageViewItem);
先顯示縮略圖,后顯示原圖
//用原圖的1/10作為縮略圖
Glide
.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.thumbnail(0.1f)
.into(iv_0);
//用其它圖片作為縮略圖
DrawableRequestBuilder<Integer> thumbnailRequest = Glide
.with(this)
.load(R.drawable.news);
Glide.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.thumbnail(thumbnailRequest)
.into(iv_0);
圖片處理
裁剪、模糊、濾鏡等。可以使用 **wasabeef/glide-transformations** , 實現Transformation 接口,或者使用抽象類BitmapTransformation, 通過transform()或bitmapTransform()來處理圖片//圓形裁剪
Glide.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.bitmapTransform(new CropCircleTransformation(this))
.into(iv_0);
//圓角處理
Glide.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL))
.into(iv_0);
//灰度處理
Glide.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.bitmapTransform(new GrayscaleTransformation(this))
.into(iv_0);
//模糊處理
Glide.with(this).load(R.drawable.demo)
.bitmapTransform(new BlurTransformation(context))
.into((ImageView) findViewById(R.id.image));
//其它變換...
自定義轉換
public class BlurTransformation extends BitmapTransformation {
public BlurTransformation(Context context) {
super( context );
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return null; // todo
}
@Override
public String getId() {
return null; // todo
}
}
其中getId() :描述了這個轉換的唯一標識符,將作為緩存系統的一部分
可以使用單種轉換和多種轉換,如多種轉換:
Glide
.with( context )
.load( eatFoodyImages[1] )
.transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) )
.into( imageView2 );
回調 Target
SimpleTarget target 泛型:Bitmap,GlideDrawable,GifDrawable 其中使用字段聲明target’而不是使用匿名內部類的形式,可以避免被垃圾回收機制回收,而回調為空的現象。private SimpleTarget target = new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// do something with the bitmap
// for demonstration purposes, let's just set it to an ImageView
imageView1.setImageBitmap( bitmap );
}
};
private void loadImageSimpleTarget() {
Glide
.with( context ) // could be an issue!
.load( eatFoodyImages[0] )
.asBitmap()
.into( target );
}
Target生命周期
with( context ):關系到生命周期。如果請求需要在 activity 生命周期之外去做時,需要使用:private void loadImageSimpleTargetApplicationContext() {
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[1]
.asBitmap()
.into( target2 );
}
Target 指定尺寸
使用ImageView 作為參數給 .into()的時候,Glide 會用 ImageView 的大小去限制圖像的大小 但是target并沒有已知的大小,如果知道圖片大小則應指出,減少內存消耗。private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
imageView2.setImageBitmap( bitmap );
}
};
private void loadImageSimpleTargetApplicationContext() {
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[1] )
.asBitmap()
.into( target2 );
}
ViewTarget
常用于自定以控件中,比如自定義控件中組合了ImageView控件,如下 public class FutureStudioView extends FrameLayout { ImageView iv; TextView tv;public void initialize(Context context) {
inflate( context, R.layout.custom_view_futurestudio, this );
iv = (ImageView) findViewById( R.id.custom_view_image );
tv = (TextView) findViewById( R.id.custom_view_text );
}
public FutureStudioView(Context context, AttributeSet attrs) {
super( context, attrs );
initialize( context );
}
public FutureStudioView(Context context, AttributeSet attrs, int defStyleAttr) {
super( context, attrs, defStyleAttr );
initialize( context );
}
public void setImage(Drawable drawable) {
iv = (ImageView) findViewById( R.id.custom_view_image );
iv.setImageDrawable( drawable );
}
}
使用如下方法給自定義控件中的ImageView設置圖片
private void loadImageViewTarget() {
FutureStudioView customView = (FutureStudioView) findViewById( R.id.custom_view );
//傳遞了參數 customView
viewTarget = new ViewTarget<FutureStudioView, GlideDrawable>( customView ) {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
//調用了FutureStudioView的setImage方法
this.view.setImage( resource.getCurrent() );
}
};
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[2] )
.into( viewTarget );
}
NotificationTarget
用于加載圖片到通知欄和應用小部件中的動畫
animate() :可以加載資源文件animate.xml文件 或者 屬性動畫: - ViewPropertyAnimation - ViewAnimation - NoAnimation - DrawableCrossFadeViewAnimationViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {
@Override
public void animate(View view) {
// if it's a custom view class, cast it here
// then find subviews and do the animations
// here, we just use the entire view for the fade animation
view.setAlpha( 0f );
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
fadeAnim.setDuration( 2500 );
fadeAnim.start();
}
};
Glide
.with( context )
.load( eatFoodyImages[1] )
.animate( animationObject )
.into( imageView2 );
Glide module
Glide module 是一個抽象方法,全局改變 Glide 行為的一個方式。 前面單策略的定義中都用到了GlideBuilder類 如果你需要訪問 GlideBuilder,你需要去實現一個 GlideModule 接口的公共類public class FileGlideModule implements GlideModule{
@Override
public void applyOptions(final Context context, GlideBuilder builder) {
//builder 內的所有方法你都可以設置。
// builder.setDiskCache(new InternalCacheDiskCacheFactory(context));
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
/* builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/com.leying365");
return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
}
});*/
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
builder.setBitmapPool(new LruBitmapPool(calculator.getBitmapPoolSize()));
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
最終通過 來生效
常用方法:
- setMemoryCache(MemoryCache memoryCache)
- setBitmapPool(BitmapPool bitmapPool)
- setDiskCache(DiskCache.Factory diskCacheFactory)
- setDiskCacheService(ExecutorService service)
- setResizeService(ExecutorService service)
- setDecodeFormat(DecodeFormat decodeFormat)
網絡庫
Glide 使用ModeLoader 接口來 集成網絡庫,Glide提供了兩種網絡庫 的實現,分別為OkHttp 和 Volley。
在build.gradle中添加如下依賴,glide會默認使用OKhttp來做所有的網絡連接
dependencies {
// your other dependencies
// ...
// Glide
compile 'com.github.bumptech.glide:glide:3.7.0'
// Glide's OkHttp Integration
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
}
上面會將必要的GlideModule 到你的 Android.Manifest中。
緩存與失效機制
Glide 通過 url、viewwidth、viewheight、屏幕的分辨率等以一種散列算法生成一個獨有、安全的文件名作為key保存到disk上.因為其是通過一個散列算法來實現的,因此很難定位文件的緩存,幸好Glide提供了signature()方法允許將一個附加的數據加入到緩存key當中,可以用來保證緩存的及時性.
系統默認實現了MediaStoreSignature,StringSignature.
Glide.with(fragment)
.load(mediaStoreUri)
.signature(new MediaStoreSignature(mimeType, dateModified, orientation))
.into(view);
當然也可以自己來實現Signature
public class MSignature implements Key {
@Override
public boolean equals(Object o) {
//...
}
@Override
public int hashCode() {
//...
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(ByteBuffer.allocate(Integer.SIZE)
.putInt(signature).array());
}
}
極端情況,不緩存可以用diskCacheStrategy(DiskCacheStrategy.NONE.)來實現
圖片下載
Glide除了提供into方法來加載圖片外,也提供了downloadOnly方法來實現圖片下載.
FutureTarget<File> future = Glide.with(applicationContext)
.load(yourUrl)
.downloadOnly(500, 500);
File cacheFile = future.get();
下載之后可以通過如下方式來加載圖片
Glide.with(yourFragment)
.load(yourUrl)
//DiskCacheStrategy.ALL或者DiskCacheStrategy.SOURCE可以保證程序會先去讀緩存文件
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(yourView);
如果想獲取一張圖片的Bitmap,可以使用如下方式
//此方法需要try/catch處理,并且最好在子線程中,否則會阻塞主線程
Bitmap myBitmap = Glide.with(applicationContext)
.load(yourUrl)
.asBitmap()
.centerCrop()
//設置大小
.into(500, 500)
.get()
圖片模糊處理
使用Glide加載圖片,將模糊圖片設置為背景,代碼如下:
Glide.with(this).load(mImageCover)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
blur(resource,ivCover,24);
ivCover.setImageBitmap(resource);
}
});
//blur方法,將圖片模糊處理添加到背景中
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private void blur(Bitmap bkg, View view, float radius) {
/*view.getMeasuredWidth(),
view.getMeasuredHeight(),*/
Bitmap overlay = Bitmap.createBitmap(
bkg.getWidth(),
bkg.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(bkg, -view.getLeft(),
-view.getTop(), null);
RenderScript rs = RenderScript.create(this);
Allocation overlayAlloc = Allocation.createFromBitmap(
rs, overlay);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
rs, overlayAlloc.getElement());
blur.setInput(overlayAlloc);
blur.setRadius(radius);
blur.forEach(overlayAlloc);
overlayAlloc.copyTo(overlay);
view.setBackground(new BitmapDrawable(
getResources(), overlay));
rs.destroy();
}
//圖片模糊類,使用方法如下:
/*BlurBuilder builder = new BlurBuilder();
Bitmap bitmap = builder.blur(this, bmp);
image.setImageBitmap(bitmap);*/
public class BlurBuilder {
private static final float BITMAP_SCALE = 0.2f;
private static final float BLUR_RADIUS = 8.75f;
public static Bitmap blur(Context context, Bitmap image) {
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
裁剪、模糊、濾鏡等。可以使用 wasabeef/glide-transformations
智能推薦
第三方庫pymysql
python在操作mysql數據庫最常用的第三方庫是pymysql,使用該模塊需要使用pip工具進行安裝。 如果已經安裝就會顯示已經安裝,也可以通過pip list命令來是否安裝 安裝以后,安裝mysql數據庫服務器,可在該頁面根據相應的操作系統https://dev.mysql.com/downloads/下載安裝包進行安裝,安裝過程請自行百度,這里不做介紹。 安裝完...
python第三方庫
概述 系統標準庫是安裝Python解釋器時,自帶安裝的一些最基本最常用的的Python類庫,它們的位置是:解釋器安裝目錄/Lib/; 光有系統標準庫是遠遠不能滿足多樣化的開發需求的,我們還常常要使用到一些第三方類庫,它們的位置是:解釋器安裝目錄/Lib/site-packages/; 安裝第三方類庫: Python解釋器自帶一個包管理工具pip.exe,它的位置是:解釋器安裝目錄/Scripts/...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
猜你喜歡
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...