This can be done in many ways.
Option one using a custom Layout
@Composable
private fun TextLayout(
modifier: Modifier,
padding: Dp = 32.dp,
content: @Composable () -> Unit
) {
val density = LocalDensity.current
val paddingInPx = with(density) { padding.roundToPx() }
Layout(modifier = modifier, content = content) { measurables, constraints ->
require(measurables.size == 2)
val placeables: List<Placeable> = measurables.map { measurable: Measurable ->
measurable.measure(constraints.copy(minWidth = 0, minHeight = 0))
}
val topPlaceable = placeables.first()
val centerPlaceable = placeables.last()
val height = centerPlaceable.height
val totalHeight = constraints.maxHeight
val verticalCenter = (totalHeight - height)/2
layout(constraints.minWidth, totalHeight) {
centerPlaceable.placeRelative(0, verticalCenter)
topPlaceable.placeRelative(0, verticalCenter - height - paddingInPx)
}
}
}
Option 2 Using a Box and getting height of text using onTextLayout callback of Text.
Box(
modifier = Modifier
.fillMaxHeight()
.border(3.dp, Color.Red),
contentAlignment = Alignment.CenterStart
) {
val density = LocalDensity.current
var textHeight by remember { mutableStateOf(0.dp) }
Text(
"TextCenter",
fontSize = 20.sp,
onTextLayout = {
textHeight = with(density) {
it.size.height.toDp()
}
}
)
Text(
text = "Text",
modifier = Modifier.padding(bottom = 64.dp + textHeight * 2),
color = Color.Blue,
fontSize = 20.sp
)
}
But this option, it's only for demonstration, will have another recomposition since we update var textHeight by remember { mutableStateOf(0.dp) }
Option 3 is using a ConstraintLayout. For a simple layout that like this i don't think anyone counter any performance issues using ConstraintLayout but i always refrain using ConstraintLayout because it uses MultiMeasureLayout that comes with a serious warning
@Deprecated(
"This API is unsafe for UI performance at scale - using it incorrectly will lead " +
"to exponential performance issues. This API should be avoided whenever possible."
)
fun MultiMeasureLayout(
modifier: Modifier = Modifier,
content: @Composable @UiComposable () -> Unit,
measurePolicy: MeasurePolicy
) {
}