https://kotlinlang.org logo
#compose
Title
# compose
i

ivano

02/17/2023, 2:42 PM
90 per cent of the stack overflow responses on
@Composable invocations can only happen from the context of a @Composable function
refer to
onClick()
, instead i get this error every time i try to extract some long code from a composable function for instance a
Canvas
I cannot find IN GENERAL what this error means and so I am not able to solve my case
e

ephemient

02/17/2023, 2:44 PM
you can't call composable functions from inside Canvas onDraw either
v

vide

02/17/2023, 2:45 PM
In general, you can't call any composable functions from callbacks
e

ephemient

02/17/2023, 2:45 PM
is the error not clear?
i

ivano

02/17/2023, 2:45 PM
mmh can i paste some code?
not really
Here it is i reproduced the issue cutting a lot of code: give you version 1 not refactored that works, and version 2 that does not work
version 1 (not refactored)
Copy code
Canvas(modifier = modifier) {
    val spacePerHour = (size.width - spacing) / infos.size
    (0 until infos.size - 1 step 2).forEach { i ->
        val info = infos[i]
        val hour = info.date.hour
        drawContext.canvas.nativeCanvas.apply {
            drawText(
                hour.toString(),
                spacing + i * spacePerHour,
                size.height - 5,
                textPaint
            )
        }
    }
}
c

CLOVIS

02/17/2023, 2:53 PM
You can press CTRL Q on the opening bracket of any lambda to print its signature, if it doesn't say @Composable, then you can't call composable functions
i

ivano

02/17/2023, 2:54 PM
version 2(gives
@Composable invocations
error):
Copy code
Canvas(modifier = modifier) {
        val spacePerHour = (size.width - spacing) / infos.size
        (0 until infos.size - 1 step 2).forEach { i ->
            val info = infos[i]
            val hour = info.date.hour
            drawContext.canvas.nativeCanvas.apply {
                BuildXAxis(this, hour, spacing, i, spacePerHour, this, textPaint)
            }
        }
    }


@Composable
private fun BuildXAxis(
    canvas: NativeCanvas,
    hour: Int,
    spacing: Float,
    i: Int,
    spacePerHour: Float,
    drawScope: DrawScope,
    textPaint: Paint
) {
    canvas.drawText(
        hour.toString(),
        spacing + i * spacePerHour,
        drawScope.size.height - 5,
        textPaint
    )
}
where i extracted
BuildXAxis
method to make it the long function more readable
e

ephemient

02/17/2023, 2:55 PM
remove
@Composable
from the function if you want to use it in that position
i

ivano

02/17/2023, 2:57 PM
@ephemient it works, thanks, now i understand where the error is! @CLOVIS thank you for your tip of using ctrl+Q and also @vide for the simple english explanation about callbacks!
have a pleasant week end guys!
510 Views