Android glide图片加载库学习

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

Glide的特点

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

其它图片加载库有的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的学习也就到这里了,目前还没有在项目中用起来,大家用的过程中可能会碰到一些问题,欢迎给我评论留言,共同交流学习进步。

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

好记性不如烂笔头!

    原文作者:肖赛Soaic
    原文地址: https://www.jianshu.com/p/966f94604038
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞