How does one properly rotate text in jetpack compose and get it to do a correct layout? When I use the rotate
modifier on a Text object the text is rotated but the size taken up in the layout seems to be using the pre-rotated text width.
Here is a simple example of what I am trying to accomplish - the vertical text should be along the left side in a narrow space:
@Composable
fun MainBox() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier.padding(4.dp).background(Color.Gray),
text = "This is at the top"
)
Row(
modifier = Modifier.fillMaxWidth().weight(1f),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(4.dp).rotate(-90f),
text = "This should be vertical text on the left side"
)
Text(
modifier = Modifier.fillMaxSize().background(Color.Yellow),
textAlign = TextAlign.Center,
text = "This is a big yellow box that should take up most of the space"
)
}
}
}
However, what this shows is this.
If I shorten the text in the vertical text it only takes up a narrow space, which looks more like the layout I want.
Is there a way to intercept the layout process or some other setting to use to fix the sizes so that the vertical text takes up only one text row's width of horizontal space, but still adapts to user font size changes (so no fixed sizes)?
Answers to similar questions here and here do not solve this problem or no longer work.
My version. After a few tests it seems to work pretty well
class ComposeActivity7 : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTutorialTheme {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier
.padding(4.dp)
.background(Color.Gray),
text = "This is at the top"
)
Row(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier
.vertical()
.rotate(-90f)
.background(Color.Gray)
.padding(4.dp),
text = "This should be vertical text on the left side"
)
Text(
modifier = Modifier
.fillMaxSize()
.background(Color.Yellow),
textAlign = TextAlign.Center,
text = "This is a big yellow box that should take up most of the space"
)
}
}
}
}
}
}
fun Modifier.vertical() =
layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.height, placeable.width) {
placeable.place(
x = -(placeable.width / 2 - placeable.height / 2),
y = -(placeable.height / 2 - placeable.width / 2)
)
}
}
Result
Slightly improved variant of Sergei S, which works within parents which have Modifier.high(Intrinsic.X)
:
fun Modifier.rotateVertically(rotation: VerticalRotation) = then(
object : LayoutModifier {
override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints): MeasureResult {
val placeable = measurable.measure(constraints)
return layout(placeable.height, placeable.width) {
placeable.place(
x = -(placeable.width / 2 - placeable.height / 2),
y = -(placeable.height / 2 - placeable.width / 2)
)
}
}
override fun IntrinsicMeasureScope.minIntrinsicHeight(measurable: IntrinsicMeasurable, width: Int): Int {
return measurable.maxIntrinsicWidth(width)
}
override fun IntrinsicMeasureScope.maxIntrinsicHeight(measurable: IntrinsicMeasurable, width: Int): Int {
return measurable.maxIntrinsicWidth(width)
}
override fun IntrinsicMeasureScope.minIntrinsicWidth(measurable: IntrinsicMeasurable, height: Int): Int {
return measurable.minIntrinsicHeight(height)
}
override fun IntrinsicMeasureScope.maxIntrinsicWidth(measurable: IntrinsicMeasurable, height: Int): Int {
return measurable.maxIntrinsicHeight(height)
}
})
.then(rotate(rotation.value))
enum class VerticalRotation(val value: Float) {
CLOCKWISE(90f), COUNTER_CLOCKWISE(270f)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.