使用Glide刷新ImageView

7

我有一个ImageView和一个用Glide加载的图像:

Glide.with(ImageView.getContext())
    .load(url)
    .dontAnimate()
    .placeholder(R.drawable.placeholder)
    .signature(stringSignature)
    .into(new GlideDrawableImageViewTarget(ImageView) {
        @Override
        public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
            super.onResourceReady(drawable, anim);
            progressBar.setVisibility(View.GONE);
        }
    });

当我想要刷新图片时,我只需要使用新的签名再次运行此代码。它完美地工作,但当新的加载开始时,可见的图像立即消失。

问题

是否可能将图像保留在ImageView中,并在下载新图像后替换它?

2个回答

4

这是预期的行为。
每次调用.load(x)时,Glide会在目标和其关联的请求上调用.clear()
这就是Glide能够处理其位图池的方式,否则它将无法知道何时回收位图。
为了实现这一点,您需要在两个Targets之间切换,以下是核心思想:

    public <T> void loadNextImage(@NonNull T model,
                                  @NonNull BitmapTransformation... transformations) {
        //noinspection MagicNumber
        int hash = model.hashCode() + 31 * Arrays.hashCode(transformations);
        if (mLastLoadHash == hash) return;
        Glide.with(mContext).load(model).asBitmap().transform(transformations).into(mCurrentTarget);
        mLastLoadHash = hash;
    }

Target mCurrentTarget;



private class DiaporamaViewTarget extends ViewTarget<ImageView, Bitmap> {

        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
            mLoadedDrawable = new BitmapDrawable(mImageView.getResources(), resource);
           // display the loaded image 
            mCurrentTarget = mPreviousTarget;

2
请注意:我记得有一个情况没有处理:小部件的onStop / onStart。当设备从睡眠状态中恢复时,这会导致崩溃。不过修补应该很容易。当Glide 4发布时,我计划编写此类的更好版本。 - Teovald
你好@Teovald,你有没有想法如何在recyclerview适配器中使用多个图片?我尝试了一些修改,但是都没有成功 :-( - Tomas
你想直接将这个作为RecyclerView的项使用吗?这似乎很棘手,而且代价很高。我猜你应该特别注意在一个单元格中跟踪最后加载的图像。 顺便说一下,我正在等待Glide 4的官方发布,以便更清晰地重写这个适配器。当我编写这个适配器时,我的最小API是7,但是我可以使用更有效的绑定逻辑,因为现在的最小API为16。 - Teovald
为什么Glide需要在加载之前而不是之后调用clear(),在准备好新的位图以附加的时候呢?Glide试图解决的主要用例是在列表中加载图像。这很有意义,因为这是迄今为止最常见的用例。在列表中,当您绑定一个viewholder时,您总是清除imageView的状态,因此在内存中保留位图没有意义。另一个优点是它允许您重复使用此确切的内存空间,并使用inbitmap。 - Teovald
1
@PrimožKralj 你可以在这里看一下:https://gist.github.com/FrancoisBlavoet/f8db7faa9ae6328be327。 - Teovald
显示剩余4条评论

1
您可以将已加载的Drawable设置为下次加载的占位符,就像这样:
    private Drawable placeholder = ContextCompat.getDrawable(ctx, R.drawable.placeholder);

    public void loadImage(String url, ImageView imageView) {
        Glide.with(imageView.getContext())
            .load(url)
            .placeholder(placeholder)
            .into(new GlideDrawableImageViewTarget(imageView) {
                @Override
                public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
                    super.onResourceReady(drawable, anim);
                    placeholder = drawable;
                }
            });
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接