75 lines
2.1 KiB
Kotlin
75 lines
2.1 KiB
Kotlin
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
|
|
}
|
|
} |