目录
前言
Glide特点
Glide导入
使用方法
通过RequestOption设置属性
加载图片的回调函数
过度选项
变换
自定义GlideModule
加载gif
总结
图片加载框架目前用的比较多的是picasso和glide, 其中谷歌官方也比较推荐glide, 在前文中已经分析了picasso的原理,在这里我们就开始分析一下picasso的使用方法。其实glide的与picasso加载图片的方法和方式还是大同小异的。尤其是在picasso也吸收了glide中一些优良的方法,差异越来越小。所以只在加载图片这个模块中,其实差异不大,要根据自己项目需求来选择哪个框架。要相信,木有最好的框架,只有最适合的。闲话少说,开始讲glide的使用方法,因为glide版本比较多。 目前使用的是4.7.1,所以下面的内容就以这个版本为准。 对于以前的3.x要迁移到4.x请参考 从v3升级到v4。
为什么要使用glide呢,他总是有自己的优势的,官方有自己的介绍,我这里写写自己的体会:
1 集成简单,使用起来也很简单,几行代码搞定。
2 支持多种格式的图片,png,jpeg,jpg,webp,并且支持多个来源,文件,网络,本地。
3 它集成了activity,fragment的生命周期,实现了自动管理。相对于picasso这点要好一些。
4 高效的缓存和硬盘本地存储效率。
首先提供一下github的源码:glide源码, 如果直接下载的话,版本是最新的, 我们可以在release中找自己需要的版本。使用glide首先在项目中添加依赖:
repositories {
mavenCentral()
google()
}
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
//下面是需要的权限
如果需要混淆添加:
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
glide使用比较简单,可以直接在activity,fragment,fragmentactivity中,与picasso类似,如果只是简单的加载图片,不做其他处理,glide只需要一行代码就搞定:
//url表示加载图片地址,first表示的是显示图片的imageview
Glide.with(this).load(url).into(first);
其中this,可以代表Activity,Fragment,Fragment,也可是Context等,我们可以看下这个函数的重载情况,with函数如果传入的是fragment或者activity,那么整个加载流程会与activity/fragment的生命周期绑定,比如onpause就会停止加载,onResumed的时候就重新加载。
图中的参数都可以直接使用。glide通过load方法加载图片,glide可以加载多种形式的图片,从来load也有多种重载形式:
通过这些方法我们可以看出,可以加载多种形式的图片 。例如我们加载assets文件夹中的earth.png的图片可以如下:
Glide.with(this).load("file:///android_asset/earth.png").into(first);
上面只是加载图片的最基本的方法,在开发中肯定还有其他需求,比如占位符或者容错图片,这个时候就需要通过RequestionOption来进行设置。
RequestOptions options = new RequestOptions()
.placeholder(R.mipmap.icon) //加载成功之前占位图
.error(R.mipmap.ic_launcher) //加载错误之后的错误图
.override(100,100) //指定图片的尺寸
.fitCenter() //指定图片的缩放类型为fitCenter (等比例缩放图片,宽或者是高等于
ImageView的宽或者是高。是指其中一个满足即可不会一定铺满
imageview)
.centerCrop()//指定图片的缩放类型为centerCrop (等比例缩放图片,直到图片的宽高都
大于等于ImageView的宽度,然后截取中间的显示。)
.skipMemoryCache(true) //不使用内存缓存
.diskCacheStrategy(DiskCacheStrategy.ALL) //缓存所有版本的图像
.diskCacheStrategy(DiskCacheStrategy.NONE) //不使用硬盘本地缓存
.diskCacheStrategy(DiskCacheStrategy.DATA) //只缓存原来分辨率的图片
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) //只缓存最终的图片
;
通过如下代码的方式进行设置requestionoption
//通过apply方法将设置的属性添加到glide
Glide.with(this).load(firstUrl).apply(requestOptions).into(first);
这是一个imageview加载图片的两种设置方式。第一个是centercrop的方式。会截取中间部分铺满imageview,第二个是fitcenter方法,铺满了宽就结束了。整个紫色的部分是imageview的background,这样是为了更明显的看出效果。其他几个设置内存属性的情况,在注释中已经说明了。其实很简单,只是看需求是不是每次都需要从网络获取,或者在缓存中获取。这个就不说了。
无论设置怎样的属性,有时候我们需要图片加载的进度, glide也提供了相应的回调函数:
Glide.with(this).load(firstUrl).apply(requestOptions).listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
Log.e(TAG," the task is err0r");
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
Log.e(TAG,"&&&&&&&&&&&&&&&&&&&&&&&&the task is ok");
return false;
}
}).into(first);
这就是添加的回调方法,这个回到方法只有成功,和失败的回调,而有的时候我们的需求需要展示下载图片的进度, 这个时候,这个回调就无法满足需求了。这就需要我们自己设定了。这就涉及到了glide的自定义模块,受于篇幅的限制,这篇只讲简单的使用,这个功能在后面的博客里讲。
对于crossfade()和animate()这样的函数,控制从占位符到图片和/或缩略图到全图的交叉淡入和其他类型变换的选项,被移动到了TransitionOpetion中. 如果你想移除任何默认的过渡,可以使用 TransitionOptions.dontTransition()。
过渡动画通过 RequestBuilder 应用到请求上. 在4.0的版本上,加载图片的渐入渐出效果已经不是默认效果了。每个请求必须手动应用过渡。要为一个特定的加载应用一个交叉淡入变换效果,你可以使用:
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
Glide.with(fragment)
.load(url)
.transition(withCrossFade())
.into(imageView);
或:
Glide.with(fragment)
.load(url)
.transition(
new DrawableTransitionOptions
.crossFade())
.into(imageView);
在项目中我们经常有特殊的需求,比如圆角,比如灰化等等,这个时候需要对图片进行处理,这部分功能,在glide中通过Transformation来进行设置。
RequestOptions requestOptions = new RequestOptions();
requestOptions.override(100,100).fitCenter()
.transforms(new GlideColorTransformation(),new RoundedCorners(20));
通过requestionOption的transform方法来进行设置,GlideColorTransformation()这个类是我自己写的关于图片灰化处理的类,在前文的picasso的方法使用文章中有贴出来。而这里的其实原理是一样的,只不过需要特别注意的是变换前的bitmap不需要释放
public class GlideColorTransformation extends BitmapTransformation {
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap source, int outWidth, int outHeight) {
int width = source.getWidth();
int height = source.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
canvas.drawBitmap(source, 0, 0, paint);
//这里要特别注意,picasso重写的时候,变换的前的bitmap要自己释放,而glide不需要是否,否则也会有错。
// source.recycle();
return bitmap;
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
我们设置图片的变换,有的时候需要一次变化就可以,有的时候时候就需要多次处理才可以。而看transform,和transforms两个函数,可以看到分别对应一个和多个变换。而glide也提供了一些图片的变化类,使用的时候直接用不需要我们重写。
这个是源码中com.bumptech.glide.load.resource.bitmap目录下的类,比如CircleCrop时候图片圆形化变化,centercrop拉伸等等。大家可以自己看看。需要的时候直接拿来用。
与很多优秀的开源框架一样,glide也支持自定义属性来满足开发者的需求。而glide的自定义首先在AndroidManifest.xml中通过meta声明。
其中那么指的是类的完整路径,value的值必须是GlideMoudle。
public class MyGlideModule implements GlideModule {
@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_RGB_565));
}
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
}
}
这个是自己写的很简单的一个自定义的glidemodule,因为4.0以上的版本,对于下载图片的解码方式由变化为了: ARGB_8888, 在之前的版本使用的是RGB_565,使用565占用的内存只是8888的一半,但是呢,对于图片的色质有影响,所以4.0后又恢复到了8888, 这样画质没问题了,但是内存不可避免的变大了。我这里将他的解码方式重新变为565.
加载gif
众所周知的情况,glide比picasso多的功能是支持gif的加载。其实也是一行代码搞定:
Glide.with(this).asGif().load(R.mipmap.qingdannanniu).apply(requestOptions).into(first);
其中asGif()的方法就是告诉glide,加载的将是一个gif的格式。在加载网络图片的时候,默认是静态的png等格式,所以我们要通过这个函数通知Glide。
到这里,基本把常用的方法都大致说了一下。后面会写具体的分析。 如果有什么遗漏或者不正确的地方,请不吝赐教,留下评论。
全文参考了glide的官方网站。https://bumptech.github.io/glide/