Im working with a Canvas, but once it drawn, it re...
# compose
l
Im working with a Canvas, but once it drawn, it redraws every composition, causing non desirable effects. Anyone know how to avoid this kind of situation?
n
Put inside a composable that only receives data that should cause a redraw.
l
🤔 the case is, I only want it to draw once
Copy code
fun Background(){
    val path = Path()
    val paint = Paint()
    path.fillType = PathFillType.EvenOdd
    paint.apply {
        strokeWidth = 10f
        color = BlueRibbon
        style = PaintingStyle.Fill
        isAntiAlias = true
    }
    Canvas(modifier = Modifier
        .fillMaxSize() , onDraw = {
        val canvasWidth = size.width
        val canvasHeight = size.height/4
        val offsetForVertex = 300f
        println("$canvasHeight $canvasWidth")
        paint.shader = LinearGradientShader(from = Offset(canvasWidth, 0f), to = Offset(0f, canvasHeight), listOf(SkyBlue, BlueRibbon, Idk))
        drawIntoCanvas {
            path.moveTo(0f,canvasHeight)
            path.cubicTo(0f, canvasHeight, canvasWidth/2, canvasHeight + offsetForVertex, canvasWidth, canvasHeight)
            path.lineTo(canvasWidth, 0f)
            path.lineTo(0f, 0f)
            path.lineTo(0f, canvasHeight)
            path.close()
            it.drawPath(path, paint)
        }
    })
}
And it actually doesnt receive nothing
Oh, im dumb. Actually I had to move the path & paint init inside onDrawn 🤣
l
It's better to use drawWithCache, cache them inside the block, then use them in onDraw.
Copy code
Spacer(
    modifier = Modifier
        .fillMaxSize()
        .drawWithCache {
            val path = Path()
            // ...
            onDraw {
                drawPath(path, ...)
            }
        }
)
l
So, I shouldn’t be using a Canvas? 🤔
l
Canvas is just a wrapper of Modifier.drawBehind, and inside drawBehind you get DrawScope as this, meaning this is where your stuff gets drawn each time it needs to be drawn. If you create Path and stuff like that it will end up creating them each time it draws, which may affect the performance. In contrast, drawWithCache will give you a CacheDrawScope, but it's not a DrawScope, instead it's where you build your draw params, and you use them inside the final onDraw or other callback builders which is like drawBehind. By using drawWithCache it means stuff like Path will only gets recreated when it needs like a state inside the cache builder changes.
l
Thanks for the explanation, will switch to drawWithCache 😄
I'd like to know more about drawing and such, if you know any extra resources about, it will be appreciated 🙌