Home > other >  Align Composables on all the edges of the screen while rotated
Align Composables on all the edges of the screen while rotated

Time:12-24

I can't seem to figure out how to align in Jetpack Compose. Here's what I want it to look:

enter image description here

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:

  1. Modifier.fillMaxSize() makes all your items as big as the parent, and as they're placed inside a Box container - only the top one will be visible. This modifier isn't needed for such layout.

  2. By applying contentAlignment = Alignment.CenterStart, you're layout Box children views, e.g. your text. Instead you need to align the item relative to parent container, which can be done with Modifier.align(Alignment.CenterStart)

  3. 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)
            }
        }
    
  4. 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:

  • Related