I'm working on a 3-column layout, and I want to rotate the content of one of the columns by 90 degrees:
I've tried swapping the width and height and adjusting the placement of the content, but without success.
Here’s the issue: when the box I want to rotate occupies 50% of the screen width, it works as expected. However, if the box is larger or smaller than 50%, I encounter a gap at the bottom.
Can anyone suggest a solution to ensure the rotated content fills the available space without causing a gap?
Here is my complete file:
@Composable
fun Layout() {
Row(
modifier = Modifier
.fillMaxSize()
.background(Color.Red)
) {
Row(
modifier = Modifier
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.rotate(90f)
.swapDimensions()
.background(Color.Blue)
.background(Color.LightGray)
) {
Column(
modifier = Modifier
) {
Column(modifier = Modifier.background(Color.Magenta).fillMaxWidth()) {
Text(text = "All content in this box has to be rotated 90deg")
}
Column(modifier = Modifier.background(Color.LightGray)) {
Text(text = "Text 2")
}
}
}
Column(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Green)
) {
Text(text = "This content is normal")
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Yellow)
) {
Text(text = "This content is normal")
}
}
Column(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Magenta)
) {
Text(text = "This content is normal")
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Blue)
) {
Text(text = "This content is normal")
}
}
}
}
}
fun Modifier.swapDimensions() = layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
val originalWidth = placeable.width
val originalHeight = placeable.height
val swappedWidth = originalHeight
val swappedHeight = originalWidth
layout(
swappedWidth,
swappedHeight
) {
placeable.place(
x = (swappedWidth - originalHeight) / 2,
y = (swappedHeight - originalWidth) / 2
)
}
}
@Preview(
name = "Landscape Preview",
device = "spec:width=800dp, height=400dp",
showBackground = true
)
@Composable
fun PreviewLayout() {
Layout()
}
You should calculate your Placeable dimensions by measuring available height for width calculation and height for height while change layout which do not abide parent Constraints.
Remove rotate and use only
fun Modifier.swapDimensions() = layout { measurable, constraints ->
val placeable = measurable.measure(
Constraints.fixed(constraints.maxHeight, constraints.maxWidth)
)
val originalWidth = placeable.width
val originalHeight = placeable.height
layout(
originalWidth,
originalHeight
) {
placeable.placeWithLayer(
x = 0,
y = 0,
layerBlock = {
rotationZ = 90f
}
)
}
}
@Composable
fun Layout() {
Row(
modifier = Modifier
.fillMaxSize()
.background(Color.Red)
) {
Row(
modifier = Modifier
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.swapDimensions()
.border(4.dp, Color.Cyan)
.background(Color.Blue)
.background(Color.LightGray)
) {
Column(
modifier = Modifier
) {
Column(
modifier = Modifier.border(2.dp, Color.Black).background(Color.Magenta)
.fillMaxWidth()
) {
Text(text = "All content in this box has to be rotated 90deg")
}
Column(
modifier = Modifier.border(2.dp, Color.Red).background(Color.LightGray)
) {
Text(text = "Text 2")
}
}
}
Column(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Green)
) {
Text(text = "This content is normal")
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Yellow)
) {
Text(text = "This content is normal")
}
}
Column(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Magenta)
) {
Text(text = "This content is normal")
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxSize()
.background(Color.Blue)
) {
Text(text = "This content is normal")
}
}
}
}
}