Glide 4.6.1 image flicker on custom transformation

拜拜、爱过 提交于 2020-12-15 05:16:13

问题


I have the following custom transformation (kotlin):

private class IconTransformation : BitmapTransformation() {
    companion object {
        private const val ID = "com.example.widget.IconView\$IconTransformation"
        private val ID_BYTES = ID.toByteArray()

        private const val PAINT_FLAGS = Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG
        private const val CIRCLE_CROP_PAINT_FLAGS = PAINT_FLAGS or Paint.ANTI_ALIAS_FLAG
        private val CIRCLE_CROP_SHAPE_PAINT = Paint(CIRCLE_CROP_PAINT_FLAGS)
        private val CIRCLE_CROP_BITMAP_PAINT = Paint(CIRCLE_CROP_PAINT_FLAGS).apply {
            xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        }
        private val CLEAR_PAINT = Paint().apply {
            xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
        }
    }

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update(ID_BYTES)
    }

    override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int,
            outHeight: Int): Bitmap {
        val img = TransformationUtils.fitCenter(pool, toTransform, outWidth, outHeight)
        val result = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888)
        val left = (result.width - img.width) / 2f
        val top = (result.height - img.height) / 2f
        result.setHasAlpha(true)
        Canvas(result).apply {
            drawColor(Color.TRANSPARENT)
            drawCircle(outWidth / 2f, outHeight / 2f,
                    Math.min(outWidth, outHeight) / 2f, CIRCLE_CROP_SHAPE_PAINT)
            drawBitmap(img, left, top, CIRCLE_CROP_BITMAP_PAINT)
            if (left > 0f) {
                drawRect(0f, 0f, left, outHeight.toFloat(), CLEAR_PAINT)
                drawRect(left + img.width - 1, 0f,
                        outWidth.toFloat(), outHeight.toFloat(), CLEAR_PAINT)
            }
            if (top > 0f) {
                drawRect(0f, 0f, outWidth.toFloat(), top, CLEAR_PAINT)
                drawRect(0f, top + img.height - 1,
                        outWidth.toFloat(), outHeight.toFloat(), CLEAR_PAINT)
            }
        }
        pool.put(img)
        return result
    }

    override fun hashCode(): Int = ID.hashCode()

    override fun equals(other: Any?): Boolean = other is IconTransformation
}

When I use it like below inside a recycler view, the images flicker and bounce around. From everything I read it has to do with improperly implementing updateDiskCacheKey, hashCode, and equals. From AFAIK I followed the instructions in BitmapTransformation exactly.

    Glide.with(icon)
            .load(url)
            .apply(RequestOptions()
                    .transform(IconTransformation())
                    .error(errorDrawableRes))
            .into(icon)

回答1:


My comment here might help.

I use placeholder to solve the flickering problem. dontTransform does not work in my app. After search around the source code of Glide, I find the problem might come from ImageViewTarget:

/**
   * Sets the given {@link android.graphics.drawable.Drawable} on the view using {@link
   * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
   *
   * @param placeholder {@inheritDoc}
   */
  @Override
  public void onLoadStarted(@Nullable Drawable placeholder) {
    super.onLoadStarted(placeholder);
    setResourceInternal(null);
    setDrawable(placeholder);
  }

Thus if placeholder is null, ImageView will turn blank right after every loading. So I cache the last image in the ImageView and set it as placeholder for next loading. Here is the code

// init
mGlideOpt = new RequestOptions().dontAnimate().skipMemoryCache(false);
mGlideRB = Glide.with(imageView).asBitmap();

// loading
Drawable drawable = mImageView.getDrawable();
if (drawable != null) {
    mGlideOpt = mGlideOpt.placeholder(drawable);
}
mGlideRB.apply(mGlideOpt).load(mCacheFile).into(mImageView);

Just a work around. Hope it helps.




回答2:


The issue was in the line pool.put(img) turning into the following fixed the issue:

if (img != toTransform) {
    pool.put(img)
}


来源:https://stackoverflow.com/questions/48996119/glide-4-6-1-image-flicker-on-custom-transformation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!