Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlideCompose's contentScale cannot be previewed correctly. #5431

Open
liyuhaolol opened this issue Jul 22, 2024 · 2 comments
Open

GlideCompose's contentScale cannot be previewed correctly. #5431

liyuhaolol opened this issue Jul 22, 2024 · 2 comments

Comments

@liyuhaolol
Copy link

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.
WX20240717-162611@2x
I would like to know if this issue has been addressed promptly and fixed.

@xiangning17
Copy link

+1, I meet the same problem.

@xiangning17
Copy link

@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) }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants