I can't seem to figure out how to align in Jetpack Compose. Here's what I want it to look:
Now I tried the following, but it does not work as expected: Nevermind the exact colors btw, I'm only really interested in the concept of how to position those views, each rotated 90 degrees, and aligned to the edges of the Tablet in my case
// Large green background
Box(modifier = Modifier.fillMaxSize().background(Color.DarkGray))
{
Box(
Modifier
.fillMaxSize()
.background(Color.Green),
contentAlignment = Alignment.BottomCenter
) { Text("Player 1") }
Box(
Modifier
.fillMaxSize()
.background(Color.Green)
.rotate(90f),
contentAlignment = Alignment.CenterStart
) { Text("Player 2") }
Box(
Modifier
.fillMaxSize()
.background(Color.Green)
.rotate(180f),
contentAlignment = Alignment.TopCenter,
) { Text("Player 3") }
Box(
Modifier
.fillMaxSize()
.background(Color.Green)
.rotate(-90f),
contentAlignment = Alignment.CenterEnd
) { Text("Player 4") }
}
I'm either missing an Align option, or a way to set the Pivot points for the Rotation. Any one has a suggestion?
I'm currently using:
- AS 2020.3.1 - patch 4
- Compose 1.1.0-rc01
- Kotlin 1.6.0
- Agp: 7.0.4
CodePudding user response:
Modifier.fillMaxSize()
makes all your items as big as the parent, and as they're placed inside aBox
container - only the top one will be visible. This modifier isn't needed for such layout.By applying
contentAlignment = Alignment.CenterStart
, you're layoutBox
children views, e.g. your text. Instead you need to align the item relative to parent container, which can be done withModifier.align(Alignment.CenterStart)
Modifier.rotate
won't change the view position, so you need to manually update it after rotation. To understand what's going on, you can run the following code:Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize() ) { Box(Modifier .size(100.dp, 50.dp) .border(width = 1.dp, color = Color.Red) .rotate(90f) .background(Color.Green)) }
It'll produce the following view:
As you can see, real view frame is shown with the red border, and your view has an unexpected offset. You can fix it with
Modifier.layout
, like this:fun Modifier.layout90Rotated() = layout { measurable, constraints -> val placeable = measurable.measure(constraints) layout(placeable.height, placeable.width) { placeable.place(-placeable.height, (placeable.width - placeable.height) / 2) } }
The last step is moving
Modifier.background
at the end of the modifiers list. Check out why modifiers order matters in this answer
The final code looks like this:
Box(modifier = Modifier.fillMaxSize().background(Color.DarkGray))
{
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
.background(Color.Green)
) { Text("Player 1") }
Box(
modifier = Modifier
.align(Alignment.CenterStart)
.rotate(90f)
.layout90Rotated()
.background(Color.Green)
) { Text("Player 2") }
Box(
modifier = Modifier
.align(Alignment.TopCenter)
.rotate(180f)
.background(Color.Green)
) { Text("Player 3") }
Box(
modifier = Modifier
.align(Alignment.CenterEnd)
.rotate(-90f)
.layout90Rotated()
.background(Color.Green)
) { Text("Player 4") }
}
Result: