Glide入门指南
文章主要内容翻译自 Glide 官方文档,文档地址: bumptech.github.io/glide/doc/g…
基本使用
使用 Glide 加载图片是非常简单的,一般情况下只需要一句代码:
Glide.with(fragment)
.load(myUrl)
.into(imageView);
译者注:with 方法一般接收 Activity/Fragment/Context 等,into 方法接收 ImageView 等。
再例如,有些已加载资源已经不再需要了,我们需要清除它们,这个操作也非常简单:
Glide.with(fragment).clear(imageView);
虽然清除多余的资源是个好习惯,但是你并不需要这么做。实际上,当 Glide.with 方法传入的那个 activity 或者 fragment 被销毁的时候,Glide 会自动清除和回收它所对应的资源。
自定义请求
针对那些独立的请求,Glide 提供了丰富的选项,包括图像的变换、切换动画、缓存选项等。
默认选项能直接应用在一个请求中:
Glide.with(fragment)
.load(myUrl)
.placeholder(placeholder)
.fitCenter()
.into(imageView);
也可以使用 RequestOptions 类,然后 applay 到某个请求中,而这种方式可用于在多个请求中共用同一请求选项:
RequestOptions sharedOptions =
new RequestOptions()
.placeholder(placeholder)
.fitCenter();
Glide.with(fragment)
.load(myUrl)
.apply(sharedOptions)
.into(imageView1);
Glide.with(fragment)
.load(myUrl)
.apply(sharedOptions)
.into(imageView2);
对于一些特殊情况,可以利用 generated API 进一步扩展 Glide 的 API,用以包含自定义选项。
译者注:generated API 已经被弃用
ListView 和 RecyclerView
在 ListView 或 RecyclerView 中加载图片时,如果你加载到单一的 View 中,则依然一句代码就能搞定。Glide 会自动处理 View 的复用以及请求的取消。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String url = urls.get(position);
Glide.with(fragment)
.load(url)
.into(holder.imageView);
}
你也不需要检查 url 是否为 null,当 url 为 null 的时候,Glide 会自动清空视图或者设置为你指定的 placeholder Drawable 或者 fallback Drawable(当然,这是在你指定过的前提下)。
Glide 唯一的要求就是,如果你 load into 到某个可重用的 View 或 Target,那下一次必须重新 load into,或者显式调用 clear 方法进行清除。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (isImagePosition(position)) {
String url = urls.get(position);
Glide.with(fragment)
.load(url)
.into(holder.imageView);
} else {
Glide.with(fragment).clear(holder.imageView);
holder.imageView.setImageDrawable(specialDrawable);
}
}
译者注:参考 RecyclerView 的 View 复用机制,由于 Glide 的 load into 方法是异步的,所以容易出现神奇的错误。以其中的某个场景为例,假如 RecyclerView 每页显示10个 item,每个 item 都有图片。现在,item1 已经请求了但是还没收到回复,现在直接翻页到下一页,这时候,前10个 item 的 View 被回收了,然后复用到了现在的页面中,现在 item11 也发出请求了。由于网络问题,item1 的图片可能返回得比 item11 还要晚,由于 View 的复用,他们两其实用的同一个 View,这时候后面才返回 item1 的结果就会把 item11 给覆盖,从而导致错误的显示结果。
通过 clear(View) 或者 into(View) ,将该 View 之前的请求取消掉,就能保证图片不会被错误地修改。如果忘记调用 clear 也没有重新加载,就可能发生类似前面所说的情况。
除了 View 之外的 Target
除了加载 Bitmap 和 Drawable 到 View 中,也可以异步加载到你自定义的 Target 中
Glide.with(context)
.load(url)
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<Drawable> transition) {
// 使用Drawable做一些事情
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
// 将onResourceReady提供的Drawable从所有View中移除
// 确保这个Drawable没有留下任何引用
}
});
使用自定义 Target 有一些陷阱,因此请务必查阅 Target 相关文档
后台线程
在后台线程上加载图像也可以直接使用 submit(int, int):
FutureTarget<Bitmap> futureTarget =
Glide.with(context)
.asBitmap()
.load(url)
.submit(width, height);
Bitmap bitmap = futureTarget.get();
// 使用bitmap完成一些逻辑,完成之后再执行这段代码:
Glide.with(context).clear(futureTarget);
译者注:代码块中的
futureTarget.get()执行之后会阻塞,直到结果返回。
如果你不需要在后台线程上使用 Bitmap 或 Drawable,也可以使用用与前台线程同样的方式,启动异步加载:
Glide.with(context)
.asBitmap()
.load(url)
.into(new Target<Bitmap>() {
...
});