版權聲明:你們能夠轉載,請寫明轉載申明 https://blog.csdn.net/bzlj2912009596/article/details/81702367
今天,簡單講講Android裏Glide的簡單使用。css
Android框架系列:html
一.android EventBus的簡單使用java
二.android Glide簡單使用android
對於Glide這個加載圖片的框架,不少人都在用,我以前使用的是ImageLoader,最近查資料時,發現Glide纔是Google推薦的加載圖片框架,功能很是強大,並且還有Google專人維護,要知道,ImageLoader已經沒人維護了,除了問題可沒人解答。因此有必要整理一下Glide的使用。git
Glide是谷歌爲咱們推薦的一個圖片加載庫。爲何要選擇使用Glide呢?github
- 一、代碼有人維護,不至於出現問題,項目組都搞不定的時候問題沒法解決。(ImageLoader已沒人維護了)
- 二、代碼簡潔,可讀性很好。(Fresco是一個很是優秀的庫,可是配置稍顯麻煩,同時代碼風格讀起來有些生疏)
- 三、功能強大(400多k的包,包含不少功能,例如:像加載Gif圖片就是Picasso作不到的)
下面咱們就來介紹下Glide的用法:緩存
Glide的基本使用
導入庫
compile 'com.github.bumptech.glide:glide:3.7.0'
添加代碼混淆(可加可不加)
-
-keep
public class * implements com.bumptech.glide.module.GlideModule
-
-keep
public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
-
-
-
-
-
-
-keepresourcexmlelements manifest/application/meta-
data@value=GlideModule
這個別忘了,不要粗心哦,很容易忘得,最簡單的問題,每每須要最簡單的搞定啦。網絡
-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
<uses-permission android:name="android.permission.INTERNET" />
簡單使用例子
-
-
-
public void onCreate(Bundle savedInstanceState) {
-
-
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
-
-
Glide.with(
this).load("http://goo.gl/gEgYUd").into(imageView);
-
-
-
-
-
public View getView(int position, View recycled, ViewGroup container) {
-
final ImageView myImageView;
-
-
myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container,
false);
-
-
myImageView = (ImageView) recycled;
-
-
-
String url = myUrls.get(position);
-
-
-
-
-
-
.placeholder(R.drawable.loading_spinner)
-
-
-
-
-
Glide使用詳解
加載網絡圖片
Glide.with(context).load(internetUrl).into(targetImageView);
從文件加載圖片
-
File file =
new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
-
Glide.
with(context).load(file).into(imageViewFile);
從資源id加載圖片
-
int resourceId = R.mipmap.ic_launcher;
-
Glide.
with(context).load(resourceId).into(imageViewResource);
從uri加載圖片
Glide.with(context).load(uri).into(imageViewUri);
播放本地mp4,只能是本地(獲取MP4視頻的縮略圖)
-
String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
-
Glide.
with( context ).load( Uri.fromFile( **new **File( filePath ) ) ).into( imageViewGifAsBitmap );
加載Gif圖片
-
-
Glide.
with( context ).load( gifUrl ).into( imageViewGif );
用bitMap播放Gif.asBitmap()
Glide.with( context ).load( gifUrl ).asBitmap().into( imageViewGifAsBitmap );
強制轉化爲Gif.asGif()
Glide.with( context ).load( gifUrl ).asGif().error( R.drawable.full_cake ).into( imageViewGif );
設置默認佔位圖.placeholder()
設置加載失敗的圖片.error()
Glide.with( context ).load( gifUrl ).placeholder( R.drawable.cupcake ).error( R.drawable.full_cake ).into( imageViewGif );
.fallback()
除了上面兩種‘異常狀況’,還有一種情形就是打開手機的通信錄的時候,能夠看到你給有些喜歡的人設置了照片,然而有些可憐的人並沒給有,總不能在那裏留下一片空白吧,這個時候至關於傳遞了Null,傳遞null時,這個callback方法就會被調用。app
-
-
-
.fallback( R.drawable.wuyanzu)
-
.
into( imageViewNoFade );
設置加載動畫
其實這個是默認的,可是你仍是能夠寫出來,漸顯動畫
一、.crossFade()
:Glide提供淡如淡出框架
Glide.with(context).load().placeholder(R.mipmap.ic_launcher) .error(R.mipmap.future_studio_launcher).crossFade().into(imageViewFade);
這裏還有一個.fadeFade(int duration)
,設置動畫時間。若是你不想要動畫能夠加上.dontAnimate()
二、.animate(android.R.anim.slide_in_left)
:Android系統提供,從左到右滑出加載動畫
調整圖片大小.resize(int ,int )
單位是像素,裁剪你的圖片大小。其實Glide已經會自動根據你ImageView裁剪照片來放在緩存中了。可是不想適應ImageView大小的時候,能夠調用這個方法.override()
爲ImageView指定大小。
Glide.with(context).load(image).override(600, 200) .into(imageViewResize);
裁剪圖片.fitCenter()
和.CenterCrop()
Glide清楚在合適的ImageView中加載合適的Image.當須要裁剪大小時,有個.centerCrop
方法,這個方法的裁剪會讓你的ImageView周圍不會留白,還有一個.fitCenter()
方法,表示讓你的Image徹底顯示,尺寸不對時,周圍會留白。
設置縮略圖.thumbnail()
.thumbnail()
方法的目的就是讓用戶先看到一個低解析度的圖,點開後,再加載一個高解析度的圖。
-
-
Glide.with( context ).load(image).thumbnail(
0.1f ).into( imageView2 );
一種更高級的縮略圖加載方式:
當縮略圖也須要經過網絡加載所有解析度的時候。
-
private void loadImageThumbnailRequest() {
-
DrawableRequestBuilder<
String> thumbnailRequest = Glide.with( context ).load( eatFoodyImages[2] );
-
Glide.
with( context ).load( UsageExampleGifAndVideos.gifUrl ).thumbnail( thumbnailRequest ).into( imageView3 );
-
-
Glide.with(
this).load(R.mipmap.ic_image_sample)
-
-
.bitmapTransform(
new BlurTransformation(this))
-
-
.bitmapTransform(
new RoundedCornersTransformation(this, 24, 0, RoundedCornersTransformation.CornerType.ALL))
-
-
.bitmapTransform(
new MaskTransformation(this, R.mipmap.ic_launcher))
-
-
.bitmapTransform(
new GrayscaleTransformation(this))
-
-
.bitmapTransform(
new CropCircleTransformation(this))
-
除此以外還有實現諸如馬賽克、明暗度等更多濾鏡處理:
- ToonFilterTransformation
- SepiaFilterTransformation
- ContrastFilterTransformation
- InvertFilterTransformation
- PixelationFilterTransformation
- SketchFilterTransformation
- SwirlFilterTransformation
- BrightnessFilterTransformation
- KuwaharaFilterTransformation
- VignetteFilterTransformation
Glide的緩存
用過手機的都知道,當劃上劃下一個ListView的時候,第二次都比第一次快,就是由於爲GlideView對資源進行了緩存,並且封裝的很好,甚至不須要本身去設定緩存大小,Glide會智能地本身給咱們根據設備設置緩存大小。
緩存是爲了減小或者杜絕多的網絡請求。爲了不緩存,Glide用了內存緩存和‘外存緩存機制’,而且 提供了相應的方法,徹底封裝,不須要處理細節。Glide會自動緩存到內存,除非調用.skipMemoryCache( true )
。儘管調用了這個,Glide仍是會緩存到外存,還有一種情形,就是有一張圖片,可是這張圖變化很是快,這個時候可能並不想緩存到外存中,就使用.diskCacheStrategy( DiskCacheStrategy.NONE )
。若是你兩種都不須要,能夠兩個方法組合着一塊兒使用。
自定義外存緩存機制
Glide默認會緩存Image的不少個版本,好比原圖,若是你的imageView大小的緩存。.diskCacheStrategy()
有如下幾種緩存策略:
- DiskCacheStrategy.NONE 什麼都不緩存
- DiskCacheStrategy.SOURCE 只緩存最高解析圖的image
- DiskCacheStrategy.RESULT 緩存最後一次那個image,好比有可能你對image作了轉化
- DiskCacheStrategy.ALL image的全部版本都會緩存
Glide.with( context ).load( image ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( imageViewFile );
修改緩存大小、位置、加載圖片質量
和指定HttpClent爲OkHttp同樣,只不過咱們須要配置一些信息在applyOptions()函數裏面
-
public class GlideConfigModule implements GlideModule {
-
-
public void applyOptions(Context context, GlideBuilder builder) {
-
-
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));
-
-
builder.setMemoryCache(
new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
-
-
builder.setBitmapPool(
new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
-
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
-
-
-
-
public void registerComponents(Context context, Glide glide) {
-
-
-
<meta-data android:name=
"com.example.imageloadpk.adapter.config.GlideConfigModule"
-
android:
value="GlideModule"/>
通常的圖片加載框架設置了磁盤緩存和內存緩存就好了,可是Glide還設置了一個圖片緩存。
圖片緩存 <= 內存緩存
-
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));
-
-
builder.setMemoryCache(
new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
-
-
builder.setBitmapPool(
new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
這裏Glide不只能夠緩存圖片,還能夠緩存其餘文件譬如視頻之類,也就是說能夠把他做爲咱們的緩存工具來使用,固然緩存方式仍是使用LRU。這樣咱們就沒必要再去從新集成LruCache和DiskLruCache,再去申請空間,配置。直接能夠複用Glide的。
使用緩存也加載動畫
可是,動畫默認是在圖片沒有緩存的狀況下才加載,想一想也是合理的,若是圖片已近下載到本地加載速度將會很是快,這個時候使用動畫過渡反而礙事。要讓從緩存中圖片呈現也加載動畫不能經過這種方式實現,能夠用監聽器來作。
-
private RequestListener<String, GlideBitmapDrawable> mAnimationRequestListener = new RequestListener<String, GlideBitmapDrawable>() {
-
-
public boolean onException(Exception e, String model, Target<GlideBitmapDrawable> target, boolean isFirstResource) {
-
-
-
-
-
public boolean onResourceReady(GlideBitmapDrawable resource, String model, Target<GlideBitmapDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
-
-
-
-
mIvShow.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.scale));
-
-
-
-
-
請求優先級.priority()
加載圖片確定也是有前後順序,Glide提供了.priority()
這個方法,它接收如下幾個參數:
- Priority.LOW
- Priority.NORMAL
- Priority.HIGH
- Priority.IMMEDIATE
可是Glide並不必定會按照你的順序來,只是儘可能按照你的順序來。(好比給一張很大的圖片最高的優先權,可是它並不必定比低優先級的圖先加載出來,這個時候只有使用縮略圖了)
-
Glide.with(mContext).load(Url.IMAGE_URL_TROCHILIDAE)
-
.priority(Priority.HIGH).into(mIvTonyRight);
利用callback在非標準狀況下加載圖片
上面全部的狀況都是加載圖片到ImageView中,可是並非全部的狀況都是這樣。譬如加載的控件類型不是ImageView,是個自定義的佈局。或者加載爲Background的形式。
可使用SimpleTarget類型,這裏指定他的大小爲500*100,加載爲背景圖片
-
.into(
new SimpleTarget<Drawable>(500, 100) {
-
-
public void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) {
-
mBtnClear.setBackground(resource);
-
同理下載圖片原理是同樣
-
.into(
new SimpleTarget<Bitmap>() {
-
-
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
-
-
Log.d(TAG,
"onResourceReady: save successful");
-
-
Glide中的回調:Targets
從上面的介紹,已經能夠看出Glide內部封裝了全部的細節,什麼網絡請求,什麼緩存機制,當全部都就緒事後,自動切換回UI線程,更新ImageView。Targets就是Glide中的回調,當異步線程中全部的工做作完事後返回結果。說白了就是,當請求圖片完成後,須要回調的方法。
SimpleTarget
-
private SimpleTarget target = new SimpleTarget<Bitmap>() {
-
-
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
-
-
-
imageView1.setImageBitmap( bitmap );
-
-
-
-
private void loadImageSimpleTarget() {
-
-
.load( eatFoodyImages[
0] )
-
-
-
注意事項:
一、上面這段代碼不要寫成匿名內部類的機制,緣由就是java的自動垃圾回收機制可能在圖片尚未加載好的時候就已經把你的Target回收了。
二、注意.with()裏面的參數,Glide的請求是和傳進去的Context共存亡的,若是傳一個Activity進去,當Activity GC事後,你的請求也就GC了,可是若是這樣傳:.with(context.getApplicationContext() )
.當你的Activity GC事後,請求仍是會繼續,回調仍是會繼續。
有size的Target
若是傳給into()
.的是一個ImageView,可是圖片的size比ImageView的Size打,Glide爲了節省時間,會加載小的那個size的Image。可是這對Target並不適用,覺得這裏並不知道SIze。可是若是知道image應該多大,能夠傳遞給Target.就像下面這樣:
-
private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) {
-
-
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
-
imageView2.setImageBitmap( bitmap );
-
-
-
-
private void loadImageSimpleTargetApplicationContext() {
-
Glide.with(context.getApplicationContext()); *
-
.load( eatFoodyImages[
1] )
-
-
-
ViewTarget
適用於想Glide加載到自定義View中去,
-
public class FutureStudioView extends FrameLayout {
-
-
-
-
public void nitialize(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) {
-
-
-
-
-
public FutureStudioView(Context context,AttributeSet attrs,int defStyleAttr) {
-
super( context, attrs, defStyleAttr );
-
-
-
-
public void setImage(Drawable drawable) {
-
iv = (ImageView) findViewById( R.id.custom_view_image );
-
iv.setImageDrawable( drawable );
-
-
還有notificationTarget 和AppWidget做爲擴展自行研究嘍。
監聽器配置.listener()
-
Glide.with(getContext()).load(url)
-
.listener(mRequestListener)
-
.placeholder(Drawables.sPlaceholderDrawable)
-
.error(Drawables.sErrorDrawable)
-
-
-
private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
-
-
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
-
-
Log.w(TAG,
"onException: ", e);
-
-
Log.d(TAG,
"onException: " + model);
-
-
Log.d(TAG,
"onException: " + target.getRequest().isRunning());
-
-
-
-
-
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
-
-
-
這裏的onException捕獲異常,若是返回true表示咱們本身處理掉了異常,false表示交給Glide去處理,由於咱們定義了.error()那麼就顯示error裏面的內容。
這裏onResourceReady表示是否準備資源顯示,返回true表示用戶本身已經設置好資源,包括截取操做,動畫操做之類的,準備好顯示。false表示交給Glide
如此修改後,就可以看到圖片加載日誌了,方便咱們調試
替換掉自帶的HttpClient
只需兩步
Step1:
導入須要替換的HttpClient,能夠選擇Volley也能夠選擇OkHttp,咱們使用Okhttp,在Module的build.gradle文件中配置
-
-
compile
'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'
-
compile
'com.squareup.okhttp3:okhttp:3.3.1'
-
-
-
-
compile
'com.github.bumptech.glide:volley-integration:1.4.0@aar'
-
compile
'com.mcxiaoke.volley:library:1.0.8'
-
這個版本具體選擇多少,能夠在https://github.com/bumptech/glide/wiki/Integration-Libraries這裏查詢到
Step2:
在AndroidMainfest.xml文件中寫入
這個版本具體選擇多少,能夠在https://github.com/bumptech/glide/wiki/Integration-Libraries這裏查詢到
Step2:
在AndroidMainfest.xml文件中寫入
-
<meta-data android:name=
"com.bumptech.glide.integration.okhttp3.OkHttpGlideModule"
-
android:
value="GlideModule"/>
你可能會有和我同樣的疑問,Glide能夠經過在配置清單裏面配置
能不能寫幾個meta-data標籤,一個標籤裏面配置一點參數
通過測試,發現這樣作也是能夠的。可是若是是同一種配置信息,好比你集成了OkHttp,又寫一個標籤集成Volley,最後一個會把前面的覆蓋掉。
注意事項
一、前面咱們已經學習到asGif()能夠加載gif圖,asBitmap()能夠加載靜態gif圖即gif圖的第一幀,若是非gif圖用asGif()方法加載呢?這時候會報錯。。Glide默承認以自動識別圖片格式,加載gif圖,因此在不肯定圖片格式的狀況下,不要直接寫asGif哦。
二、You cannot start a load for a destroyed activity這樣的異常如何處理?
記住不要再非主線程裏面使用Glide加載圖片,若是真的使用了,請把context參數換成getApplicationContext。但願能夠幫你避免這個問題。
三、爲何有的圖片第一次加載的時候只顯示佔位圖,第二次才顯示正常的圖片呢?
.若是你恰好使用了這個圓形Imageview庫或者其餘的一些自定義的圓形Imageview,而你又恰好設置了佔位的話,那麼,你就會遇到第一個問題。如何解決呢?
方案一: 不設置佔位;
方案二:使用Glide的Transformation API自定義圓形Bitmap的轉換。這裏是一個已有的例子;
方案三:使用下面的代碼加載圖片:
-
-
-
.placeholder(R.drawable.loading_spinner)
-
.into(
new SimpleTarget<Bitmap>(width, height) {
-
-
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
-
-
-
四、圖片大小拉伸問題
有時候你會發現網絡加載完了以後會有拉伸現象,而你的控件大小明明是自適應的呀,這是爲何呢,請你檢查下你是否設置了佔位圖,有的話請去掉就ok了。
簡單總結一下,我這裏講了Glide比較全面的用法,有如何加載圖片,Glide的緩衝設置,Glide設置圓角,Glide設置圖片的background,Glide加載GIF圖片等,你們使用的話通常瞭解加載圖片和圓角圖片就能夠了。這裏在列舉一下。
-
-
-
.load(
"http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
-
.bitmapTransform(
new CropCircleTransformation(this))
-
-
-
-
.load(
"http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
-
.bitmapTransform(
new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL))
-
android Glide簡單使用就講完了。
就這麼簡單。