Is there an equivalent to this in `Canvas` using C...
# compose
a
Is there an equivalent to this in
Canvas
using Compose? I'm looking to do this
Copy code
override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        calculatePropagation()
        canvas?.let { render() }
        postInvalidateDelayed(20)
    }
But I can't seem to find an equivalent for repeatedly drawing to Canvas. I've done a tonne of digging through docs and on here - can anyone chime in?
b
Copy code
fun Modifier.drawBehind(
    onDraw: Density.(canvas: Canvas, size: PxSize) -> Unit
) = this + DrawBackgroundModifier(onDraw)
have you tried this modifier?
a
No I haven't, thanks I'll look into this
👍 1
Is there a way with this modifier to call draw repeatedly with a delay of some form? I haven't had much experience with modifiers so trying to wrap my head around it
b
I think you can request recomposition manually with recompose method. so Recompose and simple Handler.delay could do the trick. for reference look at this link https://github.com/Foso/Jetpack-Compose-Playground/blob/master/mkdocs/compose/recompose.md
a
Aha! I think this was the method I was missing
Thank you so much
t
Maybe you should also consider use an animated state variable to trigger the recomposition automatically. Because it only makes sense to redraw when you draw something different the second time
b
@Adam Bennett Glad I managed to help
a
There's a
Canvas
composable function that will take up some layout space for you to draw into. You should separate the time pulse code from your drawing code though.
The Canvas composable uses that modifier from above as its implementation
a
Interesting, thank you. I think I've got everything I need
a
Nice post resulting from this 🙂
a
Thank you! If there's a more idiomatic way of achieving this I'd love to know
a
You had the right of it in terms of driving it from data updates. You could get a bit more efficient in the data structures used after that given the use case but the single-value state update is a good start here.
In particular you can have it skip composition entirely using the approach you arrived at, since compose knows the difference between state read by a composable function and state read by drawing code
a
Interesting feedback, thank you. I didn't know that compose could distinguish where the state was being read from, that's clever. Would be interested to see how others would approach the same problem within the compose framework
a
yep, we maintain different observation scopes. Composable functions have a local observation scope within the function body, and we also have separate observation scopes for measurement, layout and drawing of different elements.
so we can tell the difference between what part of the UI needs to do work. Much easier than trying to track manual `requestLayout()`/`invalidate()` everywhere - we record when you read state instead and infer what scopes need to invalidate from there.
a
That makes a tonne of sense. Brilliant, thanks so much for chiming in
👍 1
a
thanks for the cool demo! I'm sure Fabian and Romain will get a kick out of it too 🙂
a
I hope so!