Gilde 和 Picasso 使用笔记


开坑,想想一个 ImageView 从看到控件到显示完图片会经历哪些过程?

1.显示默认图片

即图片在加载前显示的样子,有的 App 就会做到图片上有个转圈的动画效果、或者进度条

2.显示图片

这是最基本的功能

3.网络错误显示

在图片地址错误,或者网络不好导致图片加载失败显示的图片

4.缓存图片

图片缓存节省流量避免多次加载

5.显示压缩图片/原图

有些原图太大,实际并不需要显示这么大分辨率的图片,因此需要进行压缩

有些图片则为了需要看清,即使很大也要显示原图或接近原图效果

目前项目中我使用了 Picasso 来对图片进行处理,现在我打算使用 Glide 来解决以上的几个问题,Glide 的使用方法在网上也都非常多,在这里给自己一个使用总结

Glide 一般使用方法:

Glide.with(context)
.load(url)
.placeholder(R.drawable.loading) //占位符,显示默认图片
.error(R.drawable.error)//显示加载错误的图片
.override(100,100)//自定义剪裁图片大小
.into(imageView);

Picasso 一般使用方法:

Picasso.with(context)
.load(url)
.placeholder(R.drawable.loading)
.error(R.drawable.error)
.resize(100, 100)//自定义剪裁图片大小
.centerCrop().into(img);
Glide 和 Picasso 的常用的方法和问题:
  • Glide 可以直接载入 GIF 动画,Picasso 不行。

  • Glide 占用的内存比 Picasso 高。

  • Picasso 2.5.2 在加载比较大的图片时,会显示空白。我在 vivo 手机上拍照返回就会出现这个问题,一张照片大概 4-5 M 左右。在 GitHub 上看到的解决办法是使用 Picasso 2.4 版本。

  • Glide 可以使用 CenterCrop() 和 fitCenter() 来剪裁图片;
    Picasso 可以使用 fit() 方法来让图片的宽高自适应 imageView ,前提是你的 imageView 控件不能设置成 wrap_content 。如果使用了 fit 方法,那么就不能调用 resize。

  • Glide 可以使用 .priority(Priority.HIGH) 方法来控制多个图片加载的优先度。

  • 加载成功的回调

Picasso.with(this)
.load(url)
.into(iv, new Callback() {
     @Override
    public void onSuccess() {
    Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError() {
    Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
    }
});

Glide.with(this)
.load(url)
.into(new GlideDrawableImageViewTarget(iv) {
    @Override
    public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable>animation) {
      super.onResourceReady(resource, animation);
        Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show();
       }
    }
);
  • Glide 的 GlideDrawableImageViewTarget 里还有很多其他状态的方法,一看便知其作用
GlideDrawableImageViewTarget
  • 获取加载后的 Bitmap 图片
Glide.with(this)
.load(file)
.asBitmap()//加载或使用有关 Bitmap 图片的时候需要加上
.into(new BitmapImageViewTarget(iv) {
    @Override
    public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
        super.onResourceReady(bitmap, anim);
        iv.setImageBitmap(bitmap);
        }
});

Picasso有两种方法,.get() 和 Target

    /**
     * 注意 get() 方法不能再主线程使用,会抛出异常:
     * java.lang.IllegalStateException: Method call should not happen from the main thread.
     */
        Bitmap bitmap = Picasso.with(MainActivity.this)
                .load(url)
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .get();

    //使用 Target 时,最好不要使用匿名内部类,因为 Picasso 可能在加载完成前就把 Bitmap 给回收了;
        Picasso.with(this)
                .load(file)
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .into(target);

    private com.squareup.picasso.Target target = new com.squareup.picasso.Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            //加载成功后会得到一个bitmap,可以自定义操作
            iv.setImageBitmap(bitmap);
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            // 加载失败进行相应处理
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
            
        }
    };

待续

推荐阅读更多精彩内容