之前一直使用Volley ImageLoader、或者Picasso,无意间发现Glide,觉得真的是棒棒的。
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:23.3.0'
都可以看到我不只是添加了一个依赖,还有V4包的依赖,因为它要借助V4包工作。
Glide不仅可以加载网络的图片,还可以加在本地的资源,文件资源,最重要的是还可以加在GIF格式的图片。
1)Glide加载网络图片
Glide
.with(context)
.load("http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg")
.into(mImageView);
2)从资源中加载图片
Glide
.with(context)
.load(R.mipmap.image)
.into(mImageView);
3)从文件中加载
//这个文件可能不存在于你的设备中。然而你可以用任何文件路径,去指定一个图片路径。
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "20160323153033.jpg");
Glide
.with(context)
.load(file)
.into(mImageView);
4)从Uri中加载
//这可能是任何 Uri为了演示的目的我们只是用一个 launcher icon 去创建了一个 Uri
Uri uri = resourceIdToUri(context, R.mipmap.image);
Glide
.with(context)
.load(uri)
.into(mImageView);
将id转换成Uri
public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FOREWARD_SLASH = "/";
private static Uri resourceIdToUri(Context context, int resourceId) {
return Uri.parse(ANDROID_RESOURCE + context.getPackageName() + FOREWARD_SLASH + resourceId);
}
5)加载GIF图片
加载gif图片和加载正常的图片没有什么太大的区别
String gifUrl = "http://pic.qqtn.com/file/2013/2014-12/2014122616202514075.gif";
Glide
.with( context )
.load( gifUrl )
.into( imageViewGif );
这里我们可以稍做改动
//如果你期望这个 URL 是一个 Gif,Glide 不会自动检查是否是 Gif,所以强制转换
Glide.with( context ).load( gifUrl ).asGif().into( imageViewGif );
//显示的是GIF动画的第一帧,就是静止的图片
Glide.with( context ).load( gifUrl ).asBitmap().into( imageViewGif );
//1为GIF动画加载的次数
Glide.with(MainActivity.this).load(fileGif).into(new GlideDrawableImageViewTarget(mImageView,1){
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation super GlideDrawable> animation) {
super.onResourceReady(resource, animation);
Log.e("---------->", "onResourceReady:加载完成");
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
Log.e("---------->", "onLoadFailed:" );
}
@Override
public void onLoadStarted(Drawable placeholder) {
super.onLoadStarted(placeholder);
Log.e("---------->", "onLoadStarted:" );
}
@Override
public void onStart() {
super.onStart();
Log.e("---------->", "onStart:" );
}
@Override
public void onStop() {
super.onStop();
Log.e("---------->", "onStop:" );
}
});
如果图片不会自动适配到 ImageView,调用 override(horizontalSize, verticalSize) 。这将在图片显示到 ImageView之前重新改变图片大小。
Glide
.with(context)
.load("http://p1.wmpic.me/article/2016/08/15/1471243206_FGLNjRtg_215x185.jpg")
.override(600, 200)
.into(mImageView);
CenterCrop()是一个裁剪技术,即缩放图像让它填充到 ImageView 界限内并且侧键额外的部分。ImageView 可能会完全填充,但图像可能不会完整显示。
Glide
.with(context)
.load(R.mipmap.image)
.centerCrop()
.into(imageViewResizeCenterCrop);
fitCenter() 是裁剪技术,即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。
Glide
.with(context)
.load(R.mipmap.image)
.fitCenter()
.into(imageViewResizeFitCenter);
就是说我可以先加载图片的百分之多少来显示,然后在加载原图,用户体验比较好嘿嘿
Glide
.with( context )
.load( "http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg" )
.thumbnail(0.1f)
.into(mImageView);
例如, 你传了一个 0.1f 作为参数,Glide 将会显示原始图像的10%的大小。如果原始图像有 1000x1000 像素,那么缩略图将会有 100x100 像素。因为这个图像将会明显比 ImageView 小很多,你需要确保它的 ScaleType 的设置是正确的。
//当Glide加载完会被调用
private SimpleTarget target = new SimpleTarget(){
@Override
public void onResourceReady(Bitmap resource, GlideAnimation super Bitmap> glideAnimation) {
//使用bitmap做一些事,如
mImageView.setImageBitmap(resource);
}
};
Glide
.with(this)
.load("http://img.sc115.com/dm/pc/pic/1502shayikbbuw1.jpg")
.asBitmap() //必须写,否则会报类型转化异常
.into(target); //此处为target
如果看到这样的异常You cannot start a load for a destroyed activity
请记住一句话:不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext。
原因:
Glide默认的Bitmap格式是RGB_565,这也是导致在加载图片是可能变绿的罪魁祸首。RGB_565代表8位RGB位图,而Picasso默认的Bitmap格式是ARGB_8888代表32位RGB位图,位图位数越高代表其可以存储的颜色信息越多,图像也就越逼真,这也是Picasso图像质量更好的原因了。
方案:
1、使用Glide加载图片时:
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)//是将图片原尺寸缓存到本地。
.into(imageview);
2、如果加上这一句代码图片仍然没有解决,可以将Bitmap的格式改为ARGB_8888。
首先创建一个 GlideConfiguration类去实现GlideModule,修改Bitmap的格式。
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) {
}
}
然后在AndroidManifest.xml中加入:
虽然Glide允许一个应用当中存在多个GlideModules,Glide并不会按照一个特殊的顺序去调用已注册的GlideModules,如果一个应用的多个依赖工程当中有多个相同的Modules,就有可能会产生冲突。
如果一个冲突是不可避免的,应用应该默认去定义一个自己的Module,用来手动地处理这个冲突,在进行Manifest合并的时候,可以用下面的标签排除冲突的module。
Glide的缓存功能设计成 二级缓存:内存缓存 & 硬盘缓存
缓存读取顺序:内存缓存 –> 磁盘缓存 –> 网络
二级缓存的作用不同:
// 默认开启内存缓存,用户不需要作任何设置
Glide.with(this)
.load(url)
.into(imageView);
// 可通过 API 禁用 内存缓存功能
Glide.with(this)
.load(url)
.skipMemoryCache(true) // 禁用 内存缓存
.into(imageView);
//可缓存原始图片 & 缓存转换过后的图片,用户自行设置
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
// 缓存参数说明
// DiskCacheStrategy.NONE:不缓存任何图片,即禁用磁盘缓存
// DiskCacheStrategy.ALL :缓存原始图片 & 转换后的图片
// DiskCacheStrategy.SOURCE:只缓存原始图片(原来的全分辨率的图像,即不缓存转换后的图片)
// DiskCacheStrategy.RESULT:(默认)只缓存转换后的图片(即最终的图像:降低分辨率后 / 或者转换后 ,不缓存原始图片
解决冲突参考博客
Android源码分析:手把手带你分析 Glide的缓存功能
Glide详解
一些常见问题
Glide加载图片出现浅绿色背景
Glide加载监听
Glide和自定义布局(不是继承ImageView)