关于Glide升级问题
官网链接:http://bumptech.github.io/glide/doc/migrating.html
V3版本详解:Android 图片库之Glide框架之基础
详细介绍如下
AndroidStudio配置
implementation 'com.github.bumptech.glide:glide:4.7.1'
1.基础显示图片
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
Glide.with(this)
.load(url)
.into(imageview);
和V3没有任何区别,不做过多赘述。
2.加载几种不同路径下的图片
imageview=findViewById(R.id.activity_listview_imageview);
/**
* 加载本地图片 比如sd卡中的图片
* */
File file = new File(Environment.getExternalStorageDirectory() + "/icon.png");
Glide.with(this)
.load(file)
.into(imageview);
/**
* 加载应用资源 比如mipmap下的图片
* */
int resource = R.mipmap.za;
Glide.with(this)
.load(resource)
.into(imageview);
/**
* 加载二进制流 比如从服务器获取的图片流
* */
byte[] image =XXX;
Glide.with(this)
.load(image)
.into(imageview);
/**
* 加载Uri对象 比如获取的相机相册图片
* */
Uri imageUri =XXX;
Glide.with(this)
.load(imageUri)
.into(imageview);
和V3没有任何区别,不做过多赘述。
3.添加占位符
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.placeholder(R.mipmap.ic_launcher_round)
.error(R.mipmap.ic_launcher_round);
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
如上,V4版本需要创建RequestOptions对象。然后通过RequestOptions对象来设置placeholder(加载成功前)以及error(加载失败)占位符。
4.缩略图
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
Glide.with(this)
.load(url)
.thumbnail(0.5f)
.into(imageview);
和V3没有任何区别,不做过多赘述。
5.图片大小与裁剪
实际上,使用Glide在大多数情况下我们都是不需要指定图片大小的,因为Glide会自动根据ImageView的大小来决定图片的大小,以此保证图片不会占用过多的内存从而引发OOM。但是,如果你真的有这样的需求,必须给图片指定一个固定的大小,Glide仍然是支持这个功能的。
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.override(200, 200);
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
如上,V4版本需要创建RequestOptions对象。然后通过RequestOptions对象来设置override即图片的大小。
如果你想加载一张图片的原始尺寸的话,可以使用Target.SIZE_ORIGINAL关键字。
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.override(Target.SIZE_ORIGINAL);
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
这样的话,Glide就不会再去自动压缩图片,而是会去加载图片的原始尺寸。当然,这种写法也会面临着更高的OOM风险。
6.图片的缓存
6.1.禁用内存缓存(不操作即默认开启)
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.skipMemoryCache(true);
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
如上,V4版本需要创建RequestOptions对象。然后通过RequestOptions对象来设置skipMemoryCache,传入true表示禁止内存缓存该图片。默认未开启,不设置即可。
6.2.禁用硬盘缓存(不操作即默认开启)
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
如上,V4版本需要创建RequestOptions对象。然后通过RequestOptions对象来设置diskCacheStrategy。传值及意义如下:
DiskCacheStrategy.NONE: 表示不缓存任何内容。
DiskCacheStrategy.DATA: 表示只缓存原始图片。
DiskCacheStrategy.RESOURCE: 表示只缓存转换过后的图片。
DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。
DiskCacheStrategy.AUTOMATIC: 表示让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项)。
DiskCacheStrategy.DATA 对应V3中的 DiskCacheStrategy.SOURCE
DiskCacheStrategy.RESOURCE 对应V3的 DiskCacheStrategy.RESULT
DiskCacheStrategy.AUTOMATIC是Glide 4中新增的一种缓存策略,并且在不指定diskCacheStrategy的情况下默认使用就是的这种缓存策略。
7.显示Gif和Video
显示GIF方式1:asGif()方法
imageview=findViewById(R.id.activity_main_imageview);
String url = "XXX";
Glide.with(this)
.asGif()
.load(url)
.into(imageview);
用asGif()方法,如果url对应的图片不是gif类型,则直接显示.error(R.mipmap.za)设置的图片。如果是gif类型的图片则直接显示。
显示GIF方式2:asBitmap()方法
imageview=findViewById(R.id.activity_main_imageview);
String url = "http://guolin.tech/test.gif";
Glide.with(this)
.asBitmap()
.load(url)
.into(imageview);
用asBitmap()方法,如果url对应的图片不是gif类型,直接显示图片。如果是gif类型的图片,则显示Gif的第一帧图片。
所以因为图片的格式可能不确定(有时是动图,有时是静图)所以最好两个都不加,Glide框架会自行判断
注意:
1.相比V3版本,V4版本asGif()方法和asBitmap()方法要在load(url)方法之前添加。
2.相比V3版本,V4版本还添加了几个as方法。也要在load(url)方法之前添加。
显示Video(目前只支持本地)
imageview=findViewById(R.id.activity_main_imageview);
String url = Environment.getExternalStorageDirectory()+"/123.mp4";
Glide.with(this)
.load(Uri.fromFile(new File(url)))
.into(imageview);
显示本地视频的封面。
8.各种Target
举例说明
1.SimpleTarget
泛型为Drawable:
1.此时必须删除.asBitmap()方法。
2.在onResourceReady回调方法中获取的是Drawable 所以imageview.setBackground(resource);
public void initView(){
imageview=findViewById(R.id.activity_main_imageview);
String url ="XXX";
Glide.with(this)
.load(url)
.into(mSimpleTarget);
}
private SimpleTarget mSimpleTarget = new SimpleTarget() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
imageview.setBackground(resource);
}
};
泛型为Bitmap:
1.此时必须使用.asBitmap()方法。
2.在onResourceReady回调方法中获取的是Bitmap 所以 imageview.setImageBitmap(resource);
public void initView(){
imageview=findViewById(R.id.activity_main_imageview);
String url ="XXX";
Glide.with(this)
.asBitmap()
.load(url)
.into(mSimpleTarget);
}
private SimpleTarget mSimpleTarget = new SimpleTarget() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
imageview.setImageBitmap(resource);
}
};
利用SimpleTarget类改变图片大小 替换上面实现类
private SimpleTarget mSimpleTarget = new SimpleTarget(200,200) {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
imageview.setImageBitmap(resource);
}
};
即显示的时候只需要是 200x200 的尺寸来节省时间和内存,你可以在 SimpleTarget 的回调声明中指定图片的大小。
从代码中可以看到 SimpleTarget 的对象的声明没有使用匿名对象,而是单独的声明了一个变量,这里是故意这么做的,如果使用匿名内部类的方式创建 SimpleTarget 的对象,这样会增大该对象在 Glide 完成图片请求之前就被回收的可能性。
上面Glide的with() 方法传入 Activity 或者 Fragment 时 Glide 的图片加载会与他们的生命周期关联起来,但是如果我们使用 Target 的话,这个 Target 就有可能独立于他们的生命周期以外,这时候我们就需要使用 context.getApplicationContext() 的上下文了,这样只有在应用完全停止时 Glide 才会杀死这个图片请求。
2.ViewTarget
ViewTarget的功能更加广泛,它可以作用在任意的View上。
自定义View
public class MyLayout extends RelativeLayout{
private ViewTarget viewTarget;
public MyLayout(Context context) {
super(context);
initviewTarget();
}
public MyLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initviewTarget();
}
public void initviewTarget(){
viewTarget = new ViewTarget(this) {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
MyLayout myLayout = getView();
myLayout.setBackground(resource);
}
};
}
/**
* 外界使用提供获取ViewTarget对象的方法
* */
public ViewTarget getTarget() {
return viewTarget;
}
}
布局
调用
public class MainActivity extends AppCompatActivity {
private MyLayout fatherlayout;
private ImageView imageview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
public void initView() {
fatherlayout=findViewById(R.id.activity_main_fatherlayout);
String fatherurl = "XXX";
Glide.with(this)
.load(fatherurl)
.into(fatherlayout.getTarget());
imageview = findViewById(R.id.activity_main_imageview);
String url = "XXX";
Glide.with(this)
.asBitmap()
.load(url)
.into(mSimpleTarget);
}
private SimpleTarget mSimpleTarget = new SimpleTarget(200, 200) {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
imageview.setImageBitmap(resource);
}
};
}
总结:
1.一般我们都是在ImageView上显示图片,所以大部分情况下使用第一种SimpleTarget即可满足条件。
2.如果要在其他View上显示图片,比如RelativeLayout LinearLayout等等,此时可以使用ViewTarget。
3.SimpleTarget的泛型一般为Drawable或Bitmap。ViewTarget的第二个参数也是如此。
4.V3版本泛型为GlideDrawable,而V4版本泛型为Drawable。
9.加载圆形图片
方式1:自定义BitmapTransformation类 然后使用transform方法。
BitmapTransformation实现类
public class GlideCircleTransform extends BitmapTransformation {
public GlideCircleTransform() {
super();
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
@Override
protected Bitmap transform(BitmapPool pool, 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;
// TODO this could be acquired from the pool too
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;
}
}
使用
imageview = findViewById(R.id.activity_main_imageview);
String url="XXX";
RequestOptions options = new RequestOptions()
.transform(new GlideCircleTransform());
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
方式2:直接使用RequestOptions对象的circleCrop方法。
imageview = findViewById(R.id.activity_main_imageview);
String url = "XXX";
RequestOptions options = new RequestOptions()
.circleCrop();
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
即使用RequestOptions对象的circleCrop方法即可。
10.加载圆角图片
BitmapTransformation实现类
public class GlideRoundTransform extends BitmapTransformation {
private float radius;
public GlideRoundTransform(int dp) {
super();
this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
}
}
使用
imageview = findViewById(R.id.activity_main_imageview);
String url="http://guolin.tech/test.gif";
RequestOptions options = new RequestOptions()
.transform(new GlideRoundTransform(20));
Glide.with(this)
.load(url)
.apply(options)
.into(imageview);
另外还有几个常见的方法CenterCrop、FitCenter。
RequestOptions options = new RequestOptions()
.centerCrop();
RequestOptions options = new RequestOptions()
.fitCenter();
11.更改Glide配置项
创建AppGlideModule实现类
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
}
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
}
}
applyOptions方法:更改Glide配置。
registerComponents方法:替换Glide组件。
MyAppGlideModule类在上面,我们加入了一个@GlideModule的注解,这是V4和V3最大的一个不同之处。在V3中,我们定义了自定义模块之后,还必须在AndroidManifest.xml文件中去注册它才能生效,而在Glide 4中是不需要的,因为@GlideModule这个注解已经能够让Glide识别到这个自定义模块了。
12.GlideApp使用
1.首先AndroidStudio添加配置
implementation 'com.github.bumptech.glide:glide:4.7.1'
implementation 'com.android.support:support-v4:27.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
2.创建AppGlideModule实现类,并添加@GlideModule
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
}
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
}
}
3.clean rebuild make project 后找到GlideApp类(自动生成)
4.使用
GlideApp.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(Target.SIZE_ORIGINAL)
.circleCrop()
.into(imageview);