Glide v4使用教程(2)——入门指南

562 阅读3分钟

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>() {
        ...
    });