I'm trying to create a circular Box in Jetpack Compose that dynamically sizes itself to fit the Text content it holds. The goal is for the circle to be just big enough to contain the text, taking into account that the minimum desired is 24.dp.
This is my code:
@Composable
fun MyText() {
Box(
modifier = Modifier
.sizeIn(minWidth = 24.dp, minHeight = 24.dp)
.wrapContentSize()
.aspectRatio(1f)
.background(Color.Blue, shape = CircleShape),
contentAlignment = Alignment.Center
) {
Text(
text = "1",
color = Color.White,
style = MaterialTheme.typography.bodyMedium,
)
}
}
Right now the box is not adapted to the content. This is the obtained result:
The aspectRatio
Modifier seems not to work here because it first checks the maxWidth
and maxHeight
constraints, but in your case you need minWidth
and minHeight
to be checked first.
Please try to use the layout
Modifier to adjust the measurement and placement process like this:
@Composable
fun MyText() {
val minSizePx = with(LocalDensity.current) { 24.dp.roundToPx() }
Box(
modifier = Modifier
.background(Color.Blue, shape = CircleShape)
.layout { measurable, constraints ->
val minConstraints = constraints.copy(minWidth = minSizePx, minHeight = minSizePx)
val childNode = measurable.measure(minConstraints)
val squareSize = max(childNode.height, childNode.width)
layout(squareSize, squareSize) {
val xOffset = squareSize - childNode.width
val yOffset = squareSize - childNode.height
childNode.place(xOffset / 2, yOffset / 2)
}
},
contentAlignment = Alignment.Center
) {
Text(
text = "1",
color = Color.White,
style = MaterialTheme.typography.bodyMedium,
)
}
}
Output
Alternatives
You could also write a custom Modifier as described in this article and also mentioned in this answer.