user16799920
user16799920

Reputation: 27

Android getting layout width & height for Compose

how to get the actual size values with compose? if something with the layout size has to be done before feeding the data to the view? i don't like checking. when everytime the canvas redraws

    Box {
        var count by rememberSaveable {
            mutableStateOf(0)
        }
        var states = remember { mutableListOf<Rain>() }
        Canvas(modifier = Modifier.fillMaxSize()) {
            // i need the canvas' size so i initialize the object inside this scope, and check it every time when canvas redraws
            Log.e("canvas", "repainted")
            if(states.isEmpty()) states.addAll(MutableList(300) {
                Rain(size.width, size.height)
            })
            drawRect(color = Color.Black)
            repeat(300) {
                val c = count
                val x1 = states[it].x1
                val x2 = states[it].x2
                val y1 = states[it].y1
                val y2 = states[it].y2
                val color = states[it].color
                drawLine(start = Offset(x1, y1), end = Offset(x2, y2), color = color)
                states[it]()
            }
        }
        LaunchedEffect(isPaused) {
            while (!isPaused) {
                delay(40)
                count++
            }
        }
    }

Upvotes: 0

Views: 1487

Answers (2)

Phil Dukhov
Phil Dukhov

Reputation: 87605

You can save canvasSize into a state variable, and then use derivedStateOf for your states: content of this block will only be recalculated when any of mutable states used inside are changed, in this case it'll be canvasSize

Box {
    var count by rememberSaveable {
        mutableStateOf(0)
    }
    var canvasSize by remember { mutableStateOf(Size.Unspecified) }
    val states by remember(canvasSize) {
        derivedStateOf {
            List(300) {
                Rain(canvasSize.width, canvasSize.height)
            }
        }
    }
    Canvas(
        modifier = Modifier
            .fillMaxSize()
    ) {
        canvasSize = size
        drawRect(color = Color.Blue)
        repeat(300) {
            val x1 = states[it].x1
            val x2 = states[it].x2
            val y1 = states[it].y1
            val y2 = states[it].y2
            drawLine(start = Offset(x1, y1), end = Offset(x2, y2), color = color)
        }
        states[it]()
    }
    LaunchedEffect(isPaused) {
        while (!isPaused) {
            delay(40)
            count++
        }
    }
}

Upvotes: 2

Thracian
Thracian

Reputation: 66516

DrawScope where inside has some properties one of them being size which itself has width, height, minDimension and maxDimension properties.

Canvas {
       size.width
       size.height
}

others are

@DrawScopeMarker
interface DrawScope : Density {

    /**
     * The current [DrawContext] that contains the dependencies
     * needed to create the drawing environment
     */
    val drawContext: DrawContext

    /**
     * Center of the current bounds of the drawing environment
     */
    val center: Offset
        get() = drawContext.size.center

    /**
     * Provides the dimensions of the current drawing environment
     */
    val size: Size
        get() = drawContext.size

    /**
     * The layout direction of the layout being drawn in.
     */
    val layoutDirection: LayoutDirection
...
}

Upvotes: 0

Related Questions