Reputation: 1554
I have as an example the following Composable:
@Composable
fun CustomCanvas(
) {
Box(
Modifier
.aspectRatio(1.33f)
.fillMaxWidth())
}
How do I know the size of this object after composition?
Why I want to know: I'm trying to resize and place images on a canvas. This requires knowing the size of the canvas. And no, I don't want to hardcode the size of the canvas. How to do this?
Upvotes: 25
Views: 17803
Reputation: 975
To get the actual size of the composable, you can use the LayoutCoordinates. Please see below:
var columnHeight by remember { mutableStateOf(0.dp) }
Column(modifier = Modifier
.onGloballyPositioned { layoutCoordinates: LayoutCoordinates ->
with(density) {
columnHeight = layoutCoordinates.size.height.toDp()
}
}
Upvotes: 0
Reputation: 1969
You can use Modifier.onSizeChanged to find out the size of a composable at runtime.
@Preview
@Composable
fun Example() {
Text(
text = "Hello",
modifier = Modifier.onSizeChanged {
println("Text size: $it[dp]") // Text size: 87 x 45[dp]
println("Text width: ${it.width.dp}") // Text width: 87.0.dp
println("Text height: ${it.height.dp}") // Text height: 45.0.dp
}
)
}
Upvotes: 4
Reputation: 66516
You can do this several ways. BoxWithConstraints
does not always return correct size because as the name describes it returns Constraints
. Max width or height of Constraints
doesn't always match width or height of your Composable.
Using Modifier.onSizeChanged{size:IntSize} or Modifier.onGloballyPositioned{} with a mutableState causes another recomposition which might cause change in UI on next frame.
You can check this answer out how to get exact size without recomposition and exact size on every occasion.
Upvotes: 5
Reputation: 363439
You can use the onGloballyPositioned
modifier:
var size by remember { mutableStateOf(IntSize.Zero) }
Box(Modifier.onGloballyPositioned { coordinates ->
size = coordinates.size
}) {
//...
}
Also the Canvas
has a DrawScope
which has the size
property.
Canvas() {
val canvasSize = size
}
Upvotes: 40