Android 圖片加載框架Glide

Android 圖片加載框架Glide

一:概述
Glide是目前在Android的開發中很是的受歡迎,幾乎是隨便開一個項目都會想到使用Glide當圖片加載框架
1.主要特色:
(1)支持Memory和Disk圖片緩存
(2)支持gif和webp格式圖片
(3)根據Activity/Fragment生命週期自動管理請求
(4)使用Bitmap Pool可使用Bitmap複用
(5)對於回收的Bitmap會主動調用recycle,減小系統回收壓力
2.依賴
高版本html

//這是對於Glide 4的依賴和以前Glide 有一些區別
 implementation 'com.github.bumptech.glide:glide:4.11.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
  //相比於Glide 3,這裏要多添加一個compiler的庫,這個庫是用於生成Generated API的

對於Kolin
若是你在 Kotlin 編寫的類裏使用 Glide 註解,你須要引入一個 kapt 依賴,以代替常規的 annotationProcessor 依賴android

dependencies {
 implementation 'com.github.bumptech.glide:glide:4.11.0'
 kapt 'com.github.bumptech.glide:compiler:4.11.0'
}

低版本git

implementation 'com.github.bumptech.glide:glide:3.7.0'

咱們針對於Glide 3的一些方法使用講解
二:基本使用
在AndroidManifest文件添加權限
<uses-permission android:name="android.permission.INTERNET"/>github

public class ElevenActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn;
    private ImageView imageView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_eleven);
        imageView= findViewById(R.id.iv_img);
        btn=findViewById(R.id.btn_click);
        btn.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        String url = "http://guolin.tech/book.png";
        Glide.with(this).load(url).into(imageView);//Glide請求加載圖片的最簡單
    }
}

1.加載圖片web

Glide.with(this).load(url).into(imageView);

image.png
加載網絡圖片,從文件中加載,加載資源id等緩存

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
Glide.with(context).load(file).into(imageViewFile);

2.佔位符placeholder加載時候未加載出來前先有一個佔位圖,error加載失敗圖片,fallback 在Drawable 在請求的url/model爲 null 時展現。網絡

Glide.with(this).load(url).centerCrop().placeholder(R.mipmap.ic_launcher).error(R.mipmap.login_icon).into(imageView);//佔位符
 Glide.with(this).load(url).fallback(R.mipmap.ic_launcher).into(imageView);// 若是請求的url/model爲 null 的時候展現的圖片 (若是沒有設置,仍是展現placeholder的佔位符)

3.asGif(),asBitmap()顯示gif動畫,asGif()判斷是不是gif動畫,asBitmap()能夠加載靜態gif圖即gif圖的第一幀app

Glide.with(this).load(url).asGif().into(imageView);//顯示Gif動畫
 Glide.with(this).load(url).asBitmap().into(imageView);//顯示Bitmap圖片

4.設置動畫
.crossFade() :Glide提供淡如淡出;
crossFade(int duration)//設置動畫時間
crossFade(Animation animation, int duration)//自定義動畫和時間
.dontAnimate()//取消動畫
.animate(android.R.anim.slide_in_left):Android系統提供,從左到右滑出加載動畫框架

Glide.with(this).load(url).crossFade().into(imageView);
  Glide.with(this).load(url).animate(android.R.anim.slide_in_left).into(imageView);//從左到右加載圖片

5.調整圖片大小
單位是像素,裁剪你的圖片大小。其實Glide已經會自動根據你ImageView裁剪照片來放在緩存中了。可是不想適應ImageView大小的時候,能夠調用這個方法.override()爲ImageView指定大小ide

Glide.with(this).load(url).override(100,100).animate(android.R.anim.slide_in_left).into(imageView);

6.裁剪圖片.fitCenter()和.CenterCrop()
當須要裁剪大小時,有個.centerCrop方法,這個方法的裁剪會讓你的ImageView周圍不會留白,還有一個.fitCenter()方法,表示讓你的Image徹底顯示,尺寸不對時,周圍會留白。

Glide.with(this).load(url).fitCenter().animate(android.R.anim.slide_in_left).into(imageView);

7.設置縮略圖.thumbnail()
image.png
.thumbnail()方法的目的就是讓用戶先看到一個低解析度的圖,點開後,再加載一個高解析度的圖。

Glide.with(this).load(url).fitCenter().thumbnail(0.1f).animate(android.R.anim.slide_in_left).into(imageView);

一種更高級的縮略圖加載方式:

當縮略圖也須要經過網絡加載所有解析度的時候。

private void loadImageThumbnailRequest() {
    DrawableRequestBuilder<String> thumbnailRequest = Glide.with(context.load(eatFoodyImages[2]);
    Glide.with(context).load(UsageExampleGifAndVideos.gifUrl).thumbnail(thumbnailRequest).into(imageView);
}

8.設置圖片顯示效果(圓角、圓形、高斯模糊、蒙板、裁剪等等).bitmapTransform()

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))
    .into(imageView);

除此以外還有實現諸如馬賽克、明暗度等更多濾鏡處理:

  • ToonFilterTransformation
  • SepiaFilterTransformation
  • ContrastFilterTransformation
  • InvertFilterTransformation
  • PixelationFilterTransformation
  • SketchFilterTransformation
  • SwirlFilterTransformation
  • BrightnessFilterTransformation
  • KuwaharaFilterTransformation
  • VignetteFilterTransformation

9.Gilde的緩存
緩存是爲了減小或者杜絕多的網絡請求。爲了不緩存,Glide用了內存緩存和‘外存緩存機制’,而且 提供了相應的方法,徹底封裝,不須要處理細節。Glide會自動緩存到內存,除非調用.skipMemoryCache( true )。儘管調用了這個,Glide仍是會緩存到外存,還有一種情形,就是有一張圖片,可是這張圖變化很是快,這個時候可能並不想緩存到外存中,就使用.diskCacheStrategy( DiskCacheStrategy.NONE )。若是你兩種都不須要,能夠兩個方法組合着一塊兒使用。

  • DiskCacheStrategy.NONE 什麼都不緩存
  • DiskCacheStrategy.SOURCE 僅僅只緩存原來的全分辨率的圖像
  • DiskCacheStrategy.RESULT 僅僅緩存最終的圖像,即下降分辨率後的(或者是轉換後的)
  • DiskCacheStrategy.ALL 緩存全部版本的圖像(默認行爲)

    //設置跳過內存緩存
     Glide.with(this).load(url).animate(android.R.anim.slide_in_left).skipMemoryCache(true).into(imageView);
     
    //設置硬盤緩存沒有
    Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

    10.請求的優先級.priority()
    載圖片確定也是有前後順序,Glide提供了.priority()這個方法,它接收如下幾個參數:

  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIATE
Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).priority(Priority.LOW).into(imageView);

11.監聽器配置.listener()

@Override
    public void onClick(View v) {
        String url = "http://guolin.tech/book.png";
        Glide.with(this).load(url).animate(android.R.anim.slide_in_left).listener(mRequestListener).into(imageView);


    }
    private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
        @Override
        public boolean onException(Exception e, String model, com.bumptech.glide.request.target.Target<GlideDrawable> target, boolean isFirstResource) {
            //顯示錯誤信息
            Log.w("TAG", "onException: ", e);
            //打印請求URL
            Log.d("TAG", "onException: " + model);
            //打印請求是否還在進行
            Log.d("TAG", "onException: " + target.getRequest().isRunning());
            return false;
        }

        @Override
        public boolean onResourceReady(GlideDrawable resource, String model, com.bumptech.glide.request.target.Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            return false;
        }


    };

}

這裏的onException捕獲異常,若是返回true表示咱們本身處理掉了異常,false表示交給Glide去處理,由於咱們定義了.error()那麼就顯示error裏面的內容。

這裏onResourceReady表示是否準備資源顯示,返回true表示用戶本身已經設置好資源,包括截取操做,動畫操做之類的,準備好顯示。false表示交給Glide

如此修改後,就可以看到圖片加載日誌了,方便咱們調試

12.替換掉自帶的HttpClient
導入須要替換的HttpClient,能夠選擇Volley也能夠選擇OkHttp,咱們使用Okhttp,在Module的build.gradle文件中配置

implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"

13.Glide 4使用
而Glide 4中引入了一個RequestOptions對象,將這一系列的API都移動到了RequestOptions當中。這樣作的好處是可使咱們擺脫冗長的Glide加載語句,並且還能進行本身的API封裝,由於RequestOptions是能夠做爲參數傳入到方法中的。

RequestOptions options = new RequestOptions()
        .placeholder(R.drawable.ic_launcher_background)
        .error(R.drawable.error)
        .diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
     .load(url)
     .apply(options)
     .into(imageView);

14.關於圖片變換,最後咱們再來看一個很是優秀的開源庫,glide-transformations。它實現了不少通用的圖片變換效果,如裁剪變換、顏色變換、模糊變換等等,使得咱們能夠很是輕鬆地進行各類各樣的圖片變換
添加庫

dependencies {
    implementation 'jp.wasabeef:glide-transformations:3.0.1'
}

三:使用Generated API

Generated API是Glide 4中全新引入的一個功能,它的工做原理是使用註解處理器 (Annotation Processor) 來生成出一個API,在Application模塊中可以使用該流式API一次性調用到RequestBuilder,RequestOptions和集成庫中全部的選項。
Generated API對於熟悉Glide 3的朋友來講那是再簡單不過了,基本上就是和Glide 3如出一轍的用法,只不過須要把Glide關鍵字替換成GlideApp關鍵字,以下所示:

GlideApp.with(this)
        .load(url)
        .placeholder(R.drawable.loading)
        .error(R.drawable.error)
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .override(Target.SIZE_ORIGINAL)
        .circleCrop()
        .into(imageView);

不過,有可能你的IDE中會提示找不到GlideApp這個類。這個類是經過編譯時註解自動生成的,首先確保你的代碼中有一個自定義的模塊,而且給它加上了@GlideModule註解,也就是咱們在上一節所講的內容。而後在Android Studio中點擊菜單欄Build -> Rebuild Project,GlideApp這個類就會自動生成了。

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

    @Override
    public void registerComponents(
            @NonNull Context context, @NonNull Glide glide, Registry registry) {
        // 配置glide網絡加載框架
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDefaultRequestOptions(
                new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888));
        if (BuildConfig.DEBUG) {
            builder.setLogLevel(Log.DEBUG);
        }
    }
}

能夠看到,在MyAppGlideModule類當中,咱們重寫了applyOptions()和registerComponents()方法,這兩個方法分別就是用來更改Glide配置以及替換Glide組件的。

注意在MyAppGlideModule類在上面,咱們加入了一個@GlideModule的註解,這是Gilde 4和Glide 3最大的一個不一樣之處。在Glide 3中,咱們定義了自定義模塊以後,還必須在AndroidManifest.xml文件中去註冊它才能生效,而在Glide 4中是不須要的,由於@GlideModule這個註解已經可以讓Glide識別到這個自定義模塊了
四:自定義本身的擴展類
定製本身的API須要藉助@GlideExtension和@GlideOption這兩個註解。建立一個咱們自定義的擴展類,代碼以下所示:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {

    }

    @GlideOption
    @NonNull
    public static BaseRequestOptions<?> roundCorner(@NonNull BaseRequestOptions<?> options) {
        return options.transform(new RoundedCorners(SizeUtils.dp2px(5)));
    }

}

這裏咱們定義了一個MyGlideExtension類,而且給加上了一個@GlideExtension註解,而後要將這個類的構造函數聲明成private,這都是必需要求的寫法。

接下來就能夠開始自定義API了,這裏咱們定義了一個cacheSource()方法,表示只緩存原始圖片,並給這個方法加上了@GlideOption註解。注意自定義API的方法都必須是靜態方法,並且第一個參數必須是RequestOptions,後面你能夠加入任意多個你想自定義的參數

GlideApp.with(this)
        .load(url)
        .cacheSource()
        .into(imageView);

五:Glide 4使用添加依賴

implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"

使用:

Glide.with(this).load(R.mipmap.login_icon).placeholder(R.mipmap.ic_launcher).into(imageView);
  
  //或者使用
  RequestOptions options=new RequestOptions().placeholder(R.mipmap.ic_launcher);//questOptions 容許你一次指定一系列的選項,而後對多個加載重用它們
        Glide.with(this).load(R.mipmap.login_icon).apply(options).into(imageView);
        //這樣抽取出來能夠屢次加載

自定義模塊@GlideMoudule,這樣的話就能建立一個自定模塊類
咱們重寫了applyOptions()和registerComponents()方法,這兩個方法分別就是用來更改Glide配置以及替換Glide組件的。

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

    @Override
    public void registerComponents(
            @NonNull Context context, @NonNull Glide glide, Registry registry) {
        // 配置glide網絡加載框架
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDefaultRequestOptions(
                new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888));
        if (BuildConfig.DEBUG) {
            builder.setLogLevel(Log.DEBUG);
        }
    }
}

而後Bulid-->Rebulid Project
image.png

//這樣的話就是吧Glide 換成GlideApp
 GlideApp.with(this).load(R.mipmap.login_icon).into(imageView);

自定義Api: mini()方法

@GlideExtension
public class MyGlideExtension {
    private MyGlideExtension() {

    }
    @GlideOption
    @NonNull
    public static BaseRequestOptions<?> mini(
            @NonNull BaseRequestOptions<?> options, int size) {
        return options.fitCenter().override(size);
    }
    //這是一個Api擴展,使用居中裁剪和調整圖片size大小尺寸
}

而後Bulid-->Rebulid Project
最後調用

GlideApp.with(this).load(R.mipmap.login_icon).mini(66).into(imageView);

Glide相關博客:https://guolin.blog.csdn.net/...

END:我開始在人世間漂流, 選擇過大大小小的夢想

相關文章
相關標籤/搜索