Android圖片加載Glide框架使用詳解

在Android開發中,圖片加載已經是必不可少的一部分,無論是新聞類App,購物類、社交類等等,已經不可能不涉及到圖片加載。現在的圖片加載框架也是很多,我們最熟悉的應該是UIL了,今天就來記錄一下Glide的使用。

老規矩,在節目開始之前,我們先來一個搞笑段子:

雖然我不會賺錢,但是我會省錢啊。我早上就看上一輛蘭博基尼,我一咬牙、一跺腳,不買!!
一下子就省了七百多萬。。

1、當前比較好的圖片加載框架
Universal Image Loader:使用最廣,很強大,但現在官方已停止維護。
Picasso:和Glide非常像,Square開發的牛逼框架。
Volley:Google官方出品。
Fresco:FaceBook出品,數據相當厲害。
Glide:今天的主角,官方推薦,專注於界面流暢的滾動。

2、簡介
創建Glide的主要目的有兩個,一個是實現平滑的圖片列表滾動效果,另一個是支持遠程圖片的獲取、大小調整和展示。它還可以加載Gif動態圖,後面再說。

3、jar包
https://github.com/bumptech/glide/releases
https://github.com/bumptech/glide/wiki

4、Gradle編譯

dependencies {  
    compile 'com.github.bumptech.glide:glide:3.5.2'  
    compile 'com.android.support:support-v4:22.0.0'  
}

5、基本使用

Glide.with(context)  
    .load("xxxx.png")  
    .into(imageView);

Glide的代碼設計採用現在流行的“流式代碼”,方法調用都是一路點點點調用,這個好處就是調用邏輯非常清晰,無論以後某個具體的實現怎麼變化,整體的流程都非常清晰,一目瞭然。

下面分別解釋三個函數

6、Glide的with()可以接受的類型有如下:

    Context context;
    Activity activity;
    FragmentActivity fragmentActivity;
    Fragment fragment;

相比Picasso只能接受Context要稍微好一點。

7、load()是加載目標資源,可以接受的參數類型有如下:

    Uri uri;
    String uriString;
    File file;
    Integer resourceId;
    byte[] model;
    String model;

這麼多種加載方式,是不是很方便。

8、into()就是加載資源完成後作什麼處理,它接受三種參數:

1into(ImageView imageView);//顯示在控件上。
    Glide.with(context)  
        .load("xxxx.png")  
        .into(imageView);

2into(Target target);//通過回調獲得加載結果。
    Glide.with(context)  
        .load(url)   
        .into(new SimpleTarget<Bitmap>(width, height) {  
            @Override   
            public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {  

            }   
        };

3into(int w, int h);//指定期望的圖片大小,返回一個future對象,要在子線程中獲取。
new Thread(new Runnable() {
        @Override
        public void run() {
            Bitmap bitmap = Glide.with(context)  
                .load("xxxx.png")  
                .into(200200)
                .get();
        }
    }).start();

into的三種用法區別是什麼呢?
第一種是直接把圖片加載出來顯示在ImageView上,你並不會得到中間結果,也就是bitmap對象。
第二種、第三種都是可以獲取到bitmap的,獲取到後怎麼處理自己決定。
第三種需要在子線程中調用。

除了with(),load(),into()三個基本的方法,Glide還有很多使用的Api。

9、設置圖片大小
.override(int w, int h);
指定加載bitmap的大小,比如原圖是500 x 500,into(100, 100),加載出的bitmap就是100 x 100。

10、加載完成動畫
.animate(Animator animator);//或者int animationId
初次加載出Bitmap時展示的動畫,可以是屬性動畫,也可以是Tween動畫。
**注意:這個動畫只在初次加載出來時使用,已經加載過了,下載再從緩存中取是不會動畫的。

11、裁剪策略
.centerCrop()
裁剪,相當於ImageView設置scaleType爲centerCrop,大圖的裁剪策略。

12、佔位和錯誤顯示
.placeHolder(int resourceId);
.error(int resourceId);
加載時和加載過程中顯示的圖片,這個圖片通常就是本地的一張資源圖片,因爲它本身就是爲了解決加載網絡圖延遲的手段,自己如果還要從網絡獲取就不合適了。

13、緩存策略
.diskCacheStrategy(DiskCacheStrategy.ALL)
這個是設置緩存策略。
DiskCacheStrategy.NONE:不緩存
DiskCacheStrategy.SOURCE:緩存原始圖片
DiskCacheStrategy.RESULT:緩存壓縮過的結果圖片
DiskCacheStrategy.ALL:兩個都緩存

14、加載gif動態圖
.asBitmap()
.asGif()
只需要加一行代碼,Glide就可以直接在ImageView上加載gif動態圖,這個還是很方便的。

Glide.with(context)
    .load("xxx.gif")
    .asGif()
    .into(imageView);

關鍵就是asGif()這行代碼,它就會自動加載成gif動態圖,如果改成asBitmap(),就是靜態圖。

15、圖片轉換transform
.tranform(Tranformation tranformation)
Tranformation:轉換,用於對bitmap進行轉換。
官方解釋:所設置的轉換方式會應用在每一幀圖片或者是gif圖片的每一個bitmap

比如我們要用Glide加載出圓角圖片,或者是圓形圖片,就要用到Transformation。
這裏寫圖片描述

具體的方法就是寫一個類繼承BitmapTransformation,然後重寫transform()方法。

<圓角圖片>

public class GlideRoundTransform extends BitmapTransformation {

    public static final int DEFAULT_CORNER_RADIO = 10;

    private static float radius = 0f;

    public GlideRoundTransform(Context context) {
        this(context, DEFAULT_CORNER_RADIO);
    }

    public GlideRoundTransform(Context context, int dp) {
        super(context);
        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }

    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName() + Math.round(radius);
    }
}

<圓形圖片>

public class GlideCircleTransform extends BitmapTransformation {
    public GlideCircleTransform(Context context) {
        super(context);
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    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.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName();
    }
}

16、移除當前Transformation
.dontTransform()

17、移除所有的動畫
.dontAnimate()

18、跳過內存緩存
.skipMemoryCache(true)

19、色彩模式
Glide 在默認的 RGB_565 格式下加載的圖片質量可以接受的話,可以什麼都不做。但如果你覺得難以接受,或者是你的實際需求對圖片的質量有更高的要求的話,你可以像下面的代碼那樣創建一個 GlideModule 子類,把 Bitmap 的格式轉換到 ARGB_8888:

public class GlideConfiguration implements GlideModule {  
    @Override  
    public void applyOptions(Context context, GlideBuilder builder) {  
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);  
    }  
    @Override  
    public void registerComponents(Context context, Glide glide) {  

    }  
}

//manifest
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration" android:value="GlideModule"/>

20、暫停\回覆請求
Glide.with(context).resumeRequests();
Glide.with(context).pauseRequests();
當列表在滑動的時候,調用pauseRequests()取消請求,滑動停止時,調用resumeRequests()恢復請求。

21、清空請求列表
Glide.clear()

22、下載圖片,並且獲取下載路徑

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Future<File> fu = Glide.with(MainActivity.this)
                    .load("https://www.baidu.com/img/bdlogo.png")
                    .downloadOnly(200, 200);
            File file = file;
            Log.e("TAG", "## path=" + file.getAbsoluteFile());
            FileInputStream fis = new FileInputStream(file);
            byte[] data = new byte[fis.available()];
            fis.read(data, 0, fis.available());
            fis.close();
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            //do something...
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

注意:必須是在子線程中使用


哎呦,差不多了,寫的好累。基本的用法就這些。以後還有新的我再更新,希望能對正在學習Glide的朋友起到點作用。

本期節目就到這裏,感謝大家的收看,我們下期再見!

發佈了40 篇原創文章 · 獲贊 88 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章