开坑,想想一个 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 里还有很多其他状态的方法,一看便知其作用
- 获取加载后的 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) {
}
};
待续
网友评论