Android glide图片加载库学习

到目前为止,网上有很多图片加载库,我就先来说说为什么选择Glide来学习。

Glide的特点

  1. 显示图片平缓流畅速度快
  2. 支持gif和webp格式图片
  3. 扩展性高可以转换各种图片效果
  4. 根据Activity/Fragment生命周期自动管理请求
  5. ...

其它图片加载库有的Glide都有,这里的特点是其它加载库没有的,还有很多特点这里就不一一列举,是不是觉得很心动,下面我们就来学习怎么使用Glide吧~

github地址:https://github.com/bumptech/glide

这里主要是介绍在Andrid Studio上使用

配置环境

在builde.gradle里面添加上

  compile 'com.github.bumptech.glide:glide:3.7.0'
  compile 'com.android.support:support-v4:19.1.0'

要说明的是glide是要依赖于support liberary v4

在AndroidManifest.xml添加所需权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

基本使用

ImageView imageView = (ImageView)findViewById(R.id.my_image_view);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);

是不是特别简单一行代码就搞定

常用配置

  1. 设置图片格式
  2. 设置缓存目录(data或SD卡)
  3. 设置内存和硬盘缓存大小

创建MyGlideModule.java(名字可以随便取)实现GlideModule接口,实现里面两个方法

public class MyGlideModule implements GlideModule{

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        //设置格式
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
        //缓存到data目录下最大50M
        //缓存目录为程序内部缓存目录/data/data/your_package_name/image_manager_disk_cache/(不能被其它应用访问)且缓存最大为250MB
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context,DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
        //缓存到外部磁盘SD卡上,字节
        //builder.setDiskCache(new ExternalCacheDiskCacheFactory(context,DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
        //设置内存缓存大小
        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) {
        //glide.register(ImageFid.class,InputStream.class, new ImageFidLoader.Factory());
    }
}

在AndroidManifest.xml配置,需要把包名更换成大家项目中MyGlideModule的包名

<application
        ...>
        <meta-data
            android:name="包名.MyGlideModule"
            android:value="GlideModule" />
</application>

设置格式ARGB_8888

builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);

设置缓存到data目录下
/data/data/your_package_name/image_manager_disk_cache/
DiskCache.Factory.DEFAULT_DISK_CACHE_DIR为默认缓存目录名image_manager_disk_cache,可以修改自己想要的名称
DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE为默认缓存大小250M,参数单位是字节Byte,250M则是 250 ×1024×1024Byte

builder.setDiskCache(
    new InternalCacheDiskCacheFactory(context,
    DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,
    DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));

设置缓存到SD卡下

builder.setDiskCache(
    new ExternalCacheDiskCacheFactory(context,
    DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, 
    DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));

设置内存缓存大小,这里设置的是默认大小的1.2倍,默认大小是多少还没有测试下,大家可以运行打印一下看看

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));

获取缓存大小和清除缓存

  • 清除内存缓存
public void clearMemory(Context context){
    // 必须在UI线程中调用
    Glide.get(context).clearMemory();
}
  • 清除磁盘缓存
public void clearDiskCache(Context context){
    // 必须在后台线程中调用,建议同时clearMemory()
    Glide.get(context).clearDiskCache();
}
  • 清除view缓存
public void clearViewCache(View view){
    Glide.clear(view);
}
  • 获取缓存大小
    public void getDiskCacheSize(Context context,TextView textView){
        //获取data下
        new GetDiskCacheSizeTask(textView).execute(new File(context.getCacheDir(),DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));
        //获取sd卡下
        //new GetDiskCacheSizeTask(textView).execute(new File(context.getExternalCacheDir(),DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));
    }


    class GetDiskCacheSizeTask extends AsyncTask<File, Long, Long>{
        private final TextView resultView;

        public GetDiskCacheSizeTask(TextView resultView) {
            this.resultView = resultView;
        }

        @Override
        protected void onPreExecute() {
            resultView.setText("Calculating...");
        }

        @Override
        protected void onProgressUpdate(Long... values) { /* onPostExecute(values[values.length - 1]); */ }

        @Override
        protected Long doInBackground(File... dirs) {
            try {
                long totalSize = 0;
                for (File dir : dirs) {
                    publishProgress(totalSize);
                    totalSize += calculateSize(dir);
                }
                return totalSize;
            } catch (RuntimeException ex) {
                final String message = String.format("Cannot get size of %s: %s", Arrays.toString(dirs), ex);
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        resultView.setText("error");
                        Toast.makeText(resultView.getContext(),message,Toast.LENGTH_LONG).show();
                    }
                });
            }
            return 0L;
        }

        @Override
        protected void onPostExecute(Long size) {
            String sizeText = android.text.format.Formatter.formatFileSize(resultView.getContext(), size);
            resultView.setText(sizeText);
        }

        private long calculateSize(File dir) {
            if (dir == null) return 0;
            if (!dir.isDirectory()) return dir.length();
            long result = 0;
            File[] children = dir.listFiles();
            if (children != null)
                for (File child : children)
                    result += calculateSize(child);
            return result;
        }
    }

加载本地资源转换

    //SD卡下图片
    public String getSDSource(String fullPath){
        return "file://"+ fullPath;
    }

    //ASSETS下图片
    public String getAssetsSource(String fileName){
        return "file:///android_asset/"+fileName;
    }

    //Raw下视频可以解析一张图片
    public String getRawSource(Context context,int rawRid){
        return "android.resource://"+context.getPackageName()+"/raw/"+rawRid;
    }
    
    //Drawable图片
    public String getDrawableSource(Context context,int drawRid){
        return "android.resource://"+context.getPackageName()+"/drawable/"+drawRid;
    }

常用方法

        Glide.with(context)
                .load(url)                                          //加载资源
                .thumbnail(0.1f)                                    //用原图的1/10作为缩略图,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示
                //.thumbnail(getDrawableRequestBuilder(context,rid))    //本地资源作为缩略图
                .centerCrop()                                       //设置scaleType
                .placeholder(null)                                  //设置资源加载过程中的占位Drawable。
                .crossFade()                                        //设置加载渐变动画
                .priority(Priority.NORMAL)                          //指定加载的优先级,优先级越高越优先加载,但不保证所有图片都按序加载。枚举Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL,Priority.LOW。默认为Priority.NORMAL。                                  
                .fallback(null)                                     //设置model为空时要显示的Drawable。如果没设置fallback,model为空时将显示error的Drawable,如果error的Drawable也没设置,就显示placeholder的Drawable。
                .error(null)                                        //设置load失败时显示的Drawable。
                .listener(listener)                                 //请求监听
                .skipMemoryCache(true)                              //设置跳过内存缓存,但不保证一定不被缓存(比如请求已经在加载资源且没设置跳过内存缓存,这个资源就会被缓存在内存中)。
                .diskCacheStrategy(DiskCacheStrategy.RESULT)        //缓存策略DiskCacheStrategy.SOURCE:缓存原始数据,DiskCacheStrategy.RESULT:缓存变换(如缩放、裁剪等)后的资源数据,DiskCacheStrategy.NONE:什么都不缓存,DiskCacheStrategy.ALL:缓存SOURC和RESULT。默认采用DiskCacheStrategy.RESULT策略,对于download only操作要使用DiskCacheStrategy.SOURCE。
                .bitmapTransform(new CropCircleTransformation(context))  //圆角裁切
                .into(imageView);      

.thumbnail(0.1f)用原图的1/10作为缩略图,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示
.thumbnail(getDrawableRequestBuilder(context,rid))用本地资源作为缩略图

    public DrawableRequestBuilder<Integer> getDrawableRequestBuilder(Context context,int drawRid){
        return Glide
                .with(context)
                .load(drawRid);
    }

.placeholder(Drawable)设置资源加载过程中的占位Drawable
.fallback(Drawable)设置为空显示的Drawable
.error(Drawable)设置加载失败显示的Drawable
.crossFade()设置加载渐变动画
.diskCacheStrategy(DiskCacheStrategy.RESULT)设置缓存策略,DiskCacheStrategy.SOURCE:缓存原始数据,DiskCacheStrategy.RESULT:缓存变换(如缩放、裁剪等)后的资源数据,DiskCacheStrategy.NONE:什么都不缓存,DiskCacheStrategy.ALL:缓存SOURC和RESULT。默认采用DiskCacheStrategy.RESULT策略,对于download only操作要使用DiskCacheStrategy.SOURCE。

转换图片效果

在builde.gradle里面添加上

compile 'jp.wasabeef:glide-transformations:2.0.1'

github地址:https://github.com/wasabeef/glide-transformations

.bitmapTransform(new RoundedCornersTransformation(context,30,0, RoundedCornersTransformation.CornerType.ALL))圆角处理

.bitmapTransform(new CropCircleTransformation(context))圆形处理
..bitmapTransform(new GrayscaleTransformation(context))灰度处理

...等等还有很多效果,感兴趣的可以上github上找找api尝试一些其它效果

如果想自定义图片效果也是可以滴

public class MyTransformation extends BitmapTransformation{

    public MyTransformation(Context context) {
        super(context);
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform,int outWidth, int outHeight) {
        Bitmap result = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
        // 如果BitmapPool中找不到符合该条件的Bitmap,get()方法会返回null,就需要我们自己创建Bitmap了
        if (result == null) {
            // 如果想让Bitmap支持透明度,就需要使用ARGB_8888
            result = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);
        }
        //创建最终Bitmap的Canvas.
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setAlpha(128);
        // 将原始Bitmap处理后画到最终Bitmap中
        canvas.drawBitmap(toTransform, 0, 0, paint);
        // 由于我们的图片处理替换了原始Bitmap,就return我们新的Bitmap就行。
        // Glide会自动帮我们回收原始Bitmap。
        return result;
    }

    @Override
    public String getId() {
        // 返回代表该变换的唯一Id,会作为cache key的一部分。
        // 注意:最好不要用getClass().getName(),因为容易受混淆影响。如果变换过程不影响缓存数据,可以返回空字符串。
        return "com.example.myapp.MyTransformation";
    }

}

Glide的学习也就到这里了,目前还没有在项目中用起来,大家用的过程中可能会碰到一些问题,欢迎给我评论留言,共同交流学习进步。

后面我也会陆续写一些其它库的学习文章,希望大家多多关注支持哈~

好记性不如烂笔头!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容