学习于:https://bumptech.github.io/glide/
http://blog.csdn.net/u013005791/article/details/74532091
GlideV4中如
centerCrop()
,placeholder()
等方法已经不能直接通过流式API的方式调用;
如果还是想通过V3版本的方式调用,官方也提供了一种解决方案:添加依赖
repositories {
mavenCentral()
}
dependencies {
compile 'com.github.bumptech.glide:glide:4.0.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0'
compile 'com.android.support:support-v4:25.3.1'
}
并且创建一个AppGlideModule
的实现类,之后Rebuild工程,然后就能找到GlideApp
对象了,然后就可以和Glide v3一样使用了;
AppGlideModule
如果注释不存在,则不会发现该模块,并且您将在日志中看到一条带有Glide日志标记的警告,该日志标记指示该模块无法找到。
接下来将在V4基础上重新学习Glide的用法;
-
RequestOptions
Glide中的大多数设置都可以使用RequestOptions
类和apply()
方法来应用;
/**
* 磁盘缓存策略:diskCacheStrategy(DiskCacheStrategy.NONE)
*
* DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
* DiskCacheStrategy.NONE 不使用磁盘缓存
* DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
* DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
* DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
*/
/**
* 优先级:priority(Priority.HIGH)
*
* Priority.LOW
* Priority.NORMAL
* Priority.HIGH
* Priority.IMMEDIATE
*/
RequestOptions options = new RequestOptions()
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.fallback(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.priority(Priority.HIGH)
.override(800,800)
.circleCrop();
// .transform(new GlideRoundTransform (context))
// .centerInside();
// .centerCrop();
Glide.with(this)
.load(R.mipmap.gifpic)
.apply(options)
.into(imageView);
**清除缓存**:
//清理磁盘缓存 需要在子线程中执行
Glide.get(this).clearDiskCache();
//清理内存缓存 可以在UI主线程中进行
Glide.get(this).clearMemory();
apply:应用ResquestOptions
对象,该方法可以调用多次,但是如果两次apply存在冲突的设置,会以最后一次为准;
placeholder(占位符):当请求成功完成时,占位符将被替换为请求的资源。如果从内存中加载所请求的资源,则占位符可能永远不会显示。如果请求失败,并且未设置error()
,占位符将继续显示。类似地,如果所请求的url / model是null并且既不设置error()
也不是fallback()
,则占位符也将继续显示;
占位符是从Android资源在主线程上加载的,所以尽可能是小的容易缓存的资源;
error:当请求永久失败时显示。如果所请求的url / model是null并且没有设置fallback()
,则也显示;
fallback:当请求的url / model是null的时候,显示fallback()
设置的资源;
CenterCrop:缩放宽和高都到达View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能超过边界;
CenterInside :如果宽和高都在View的边界内,那就不缩放,否则缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
CircleCrop :圆形且结合了CenterCrop的特性;
FitCenter:缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
但是其实完全可以在layout文件中设置ImageView为android:scaleType="centerCrop"
,Glide会自动根据这个属性设置图片的显示方式;
overrid:Glide 会根据ImageView的大小,自动限制图片缓存和内存中的大小,同时也可以调用override(width, height)限制图片的大小;
transform:自定义GlideRoundTransform
类实现圆角图片;
/**
* Created by whstywh on 2017/4/5
* GitHub:https://github.com/whstywh
* email:whstywh@gmail.com
* description:自定义Glide圆角图片类
*/
public class GlideRoundTransform extends BitmapTransformation {
public GlideRoundTransform(Context context) {
super(context);
}
/**
* 重写 生成圆角图片
*
* @param pool
* @param toTransform
* @param outWidth
* @param outHeight
* @return
*/
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
//画布中背景图片与绘制图片交集部分
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
}
-
TransitionOptions
有三种:
GenericTransitionOptions
DrawableTransitionOptions
BitmapTransitionOptions
为避免突然变化,您可以在图像切换时设置淡入淡出;
Glide.with(this)
.load(R.mipmap.gifpic)
.apply(options)
.transition(DrawableTransitionOptions.withCrossFade())
// .transition(BitmapTransitionOptions.withCrossFade())
// .transition(GenericTransitionOptions.with())
.into(imageView);
TransitionOptions并且与Glide要加载的资源类型相关;
因此,如果你要求Drawable,则需要使用交叉淡入浅出DrawableTransitionOptions.withCrossFade()
,如果您要求Bitmap,则需要使用简单的淡入淡出BitmapTransitionOptions.withCrossFade()
;如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions
;
如果要使用自定义的动画,可以使用GenericTransitionOptions.with(int viewAnimationId)
或者BitmapTransitionOptions.withCrossFade(int animationId, int duration)
或者DrawableTransitionOptions.withCrossFade(int animationId, int duration)
;
出于性能考虑,最好不要在ListView,GridView,RecycleView中使用过渡动画,可以使用.dontAnimate()
不加载动画:
RequestOptions options = new RequestOptions()
...
.dontAnimate()
- RequestBuilder
RequestBuilder<Drawable> requestBuilder = Glide.with(this)
.asGif()
// .asBitmap()
// .asDrawable()
// .asFile()
.load(R.mipmap.gifpic);
requestBuilder.thumbnail(0.1f)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
Log.d("flag", "onLoadFailed");
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
Log.d("flag", "onResourceReady");
return false;
}
})
.apply(options)
.transition()
.into(imageView);
with:方法相比Picasso而言不仅接受Context,还接受Activity,Fragment,View;
加载GIF
如果使用了
.asGif()
方法,图片会强制转换成gif图,此时传入的图片就必须是gif图,否则会报错。当然不使用.asGif()
方法同样也可以加载gif图;load:方法中可以传入联网请求的url,资源id,File;相比Picasso还支持GIF图,本地MP4播放;
thumbnail:设置缩略图,传入一个(0,1)之间的float数值时,表示缩略图为原图的十分之几,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示;如果缩略图也来自网络获取时,代码如下:
requestBuilder.thumbnail(Glide.with(this).load(thumbnailUrl))
...
.into(imageView);
listener:监听资源加载的请求状态,可以使用两个回调:onResourceReady
和onLoadFailed
,但不要每次请求都使用新的监听器,要避免不必要的内存申请,可以使用单例进行统一的异常监听和处理。
apply:应用RequestOptions
transition:应用TransitionOption
Recycle的加载优化
只在拖动和静止时加载,自动滑动时不加载。
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
switch (newState) {
case RecyclerView.SCROLL_STATE_DRAGGING:
Glide.with(MainActivity.this).resumeRequests();//加载
break;
case RecyclerView.SCROLL_STATE_SETTLING:
Glide.with(MainActivity.this).pauseRequests();//暂停加载
break;
case RecyclerView.SCROLL_STATE_IDLE:
Glide.with(MainActivity.this).resumeRequests();//加载
break;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
- Glide和Picasso的区别
Glide默认的Bitmap格式是RGB_565 ,比 Picasso的ARGB_8888格式的内存开销要小一半。
Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。而Glide加载的大小和ImageView的大小是一致的,因此内存花销更小。
Picasso和Glide在磁盘缓存策略上有很大的不同。Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。
尝试将ImageView调整成不同大小,但不管大小如何Picasso只缓存一个全尺寸的。Glide则不同,它会为每种大小的ImageView缓存一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,则需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。
另外Glide也可以既缓存全尺寸又缓存其他尺寸:
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
Glide的优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致有一些延迟。