package thumbhash import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.ColorFilter import android.graphics.Paint import android.graphics.PixelFormat import android.graphics.Rect import android.graphics.drawable.Drawable import androidx.core.graphics.withTranslation class ThumbHashDrawable( private val hash: String, private val targetWidth: Int = SIZE_UNDEFINED, // Too large a resolution will affect performance private val targetHeight: Int = SIZE_UNDEFINED, // Too large a resolution will affect performance ) : Drawable() { private val paint = Paint(Paint.ANTI_ALIAS_FLAG) private var bitmap: Bitmap? = null override fun getIntrinsicHeight(): Int { return bitmap?.height ?: targetHeight } override fun getIntrinsicWidth(): Int { return bitmap?.width ?: targetWidth } override fun onBoundsChange(bounds: Rect) { updateThumbHash(bounds) } private fun calculateSize(boundSize: Int, targetSize: Int): Int { return if (targetSize > SIZE_UNDEFINED) targetSize else boundSize } private fun updateThumbHash(bounds: Rect) { val width = calculateSize(bounds.width(), targetWidth) val height = calculateSize(bounds.height(), targetHeight) val bitmap = this.bitmap if (bitmap != null) { if (width == bitmap.width && height == bitmap.height) { return } } this.bitmap = ThumbHash.getBitmapFromHash(hash, width, height) invalidateSelf() } override fun draw(canvas: Canvas) { val bitmap = this.bitmap ?: return val rect = bounds canvas.withTranslation(rect.left.toFloat(), rect.top.toFloat()) { drawBitmap(bitmap, 0f, 0f, paint) } } override fun setAlpha(alpha: Int) { paint.alpha = alpha invalidateSelf() } override fun setColorFilter(colorFilter: ColorFilter?) { paint.colorFilter = colorFilter invalidateSelf() } override fun getOpacity(): Int { return PixelFormat.OPAQUE } companion object { internal const val SIZE_UNDEFINED = -1 } }