Open liyuhaolol opened 3 months ago
+1, I meet the same problem.
@liyuhaolol 用这个自定义的GlidePainter可以处理: Image(painter = painterGlide(model), contentDescription = null, modifier = modifier, contentScale = contentScale)
import android.content.Context
import android.graphics.drawable.Drawable
import android.graphics.drawable.PictureDrawable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.withSave
import androidx.compose.ui.platform.LocalContext
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import kotlin.math.roundToInt
/**
* Author: xiangning
* Date: 2024/8/14 22:15
* Description:
*/
class GlidePainter(val context: Context, val model: Any) : Painter() {
private var drawInvalidateTick by mutableStateOf(0)
private var drawableIntrinsicSize by mutableStateOf(Size.Unspecified)
private var target: Target? = null
private var drawable: Drawable? = null
override val intrinsicSize: Size
get() = drawableIntrinsicSize
override fun DrawScope.onDraw() {
lazyStart(size)
drawIntoCanvas { canvas ->
// Reading this ensures that we invalidate when invalidateDrawable() is called
drawInvalidateTick
val d = drawable ?: return@drawIntoCanvas
// Update the Drawable's bounds
d.setBounds(0, 0, size.width.roundToInt(), size.height.roundToInt())
canvas.withSave {
d.draw(canvas.nativeCanvas)
}
}
}
private fun lazyStart(size: Size) {
if (size.isEmpty()) {
return
}
var oldW = 0
var oldH = 0
target?.getSize { width, height ->
oldW = width
oldH = height
}
val newW = size.width.toInt()
val newH = size.height.toInt()
// 只有新尺寸比之前的大才重新加载,不然就用之前的进行缩放也是可以的
if (oldW >= newW && oldH >= newH) {
return
}
Glide.with(context).clear(target)
target = Glide.with(context)
.load(model)
.into(Target(newW, newH))
}
private inner class Target(width: Int, height: Int) : CustomTarget<Drawable>(width, height) {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
drawable = resource
drawableIntrinsicSize = Size(resource.intrinsicWidth.toFloat(), resource.intrinsicHeight.toFloat())
drawInvalidateTick++
}
override fun onLoadFailed(errorDrawable: Drawable?) {
clearState()
}
override fun onLoadCleared(placeholder: Drawable?) {
clearState()
}
private fun clearState() {
if (target !== this) {
return
}
drawable = null
drawableIntrinsicSize = Size.Unspecified
drawInvalidateTick++
}
}
}
@Composable
@Stable
fun painterGlide(model: Any): Painter {
val context = LocalContext.current
return remember(model) { GlidePainter(context, model) }
}
I'm using
implementation "com.github.bumptech.glide:compose:1.0.0-beta01"
. When I set the contentScale for GlideImage, the preview does not display the contentScale correctly. In the image below, the left side is using Glide and the right side is using Coil. I would like to know if this issue has been addressed promptly and fixed.