How do layouts work in Jetpack Compose and how do they relate to XML?

Viewed 2382

I have some text. I want to centre it on the screen. I am using Jetpack Compose. How do I do this? I know that there are three types of layouts in Jetpack Compose.

  • Box
  • Column
  • Horizontal

Which one should I use? I don't know how layouts work. Are they full screen by default like in XML? If so, how do I position elements like ConstraintLayout? How do I set padding and margin from only one side and how do I link elements?

1 Answers

I guess all your questions can be clarified if you follow the Compose Pathway. But I'll try to summarize for you...

You can organize your components using one of the following "layout managers" (which in Compose are just called layouts):

  • Column (similar to LinearLayout with vertical orientation)
  • Row (similar to LinearLayout with horizontal orientation)
  • Box (similar to FrameLayout)
  • and ConstraintLayout. If you need something different of these, you can create a custom layout using the Layout composable.

"Which one should I use?" You can use any of these, depending of the case... To simply display a text in the center of the screen, you can achieve with all of them.

Using Column:

Column(
    Modifier.fillMaxSize(), // to fill the whole screen
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text(text = "Hello")
}

Using Box

Box(
    Modifier.fillMaxSize()
) {
    Text(text = "Hello",
        modifier = Modifier.align(Alignment.Center))
}

"Are they full screen by default like in XML?" No, they are "wrap_content" by default.

"how do I position elements like ConstraintLayout? How do I set padding and margin from only one side and how do I link elements?" You need to declare the references to the components and then positioning them accordingly.

Here is a simple example...

ConstraintLayout(modifier = Modifier.fillMaxSize().padding(16.dp)) {
    // Creating refs...
    val (text1Ref, edit1Ref, btn1Ref, btn2Ref) = createRefs()
    Text("Name", 
        // Linking the reference to this component
        modifier = Modifier.constrainAs(text1Ref) {
        // linking the top of this component to the parent top
        top.linkTo(parent.top)
        centerHorizontallyTo(parent)
    })
    TextField(
        value = "",
        onValueChange = {},
        label = { Text("Name") },
        modifier = Modifier.padding(top = 8.dp)
            .constrainAs(edit1Ref) {
                start.linkTo(parent.start)
                end.linkTo(parent.end)
                // linking this component with the previous component
                top.linkTo(text1Ref.bottom)
            })
    Button(onClick = {},
        content = { Text("OK") },
        modifier = Modifier.padding(top = 8.dp).constrainAs(btn1Ref) {
            end.linkTo(edit1Ref.end)
            top.linkTo(edit1Ref.bottom)
        }
    )
    TextButton(onClick = {},
        content = { Text("Cancel") },
        modifier = Modifier.padding(end = 8.dp)
            .constrainAs(btn2Ref) {
                end.linkTo(btn1Ref.start)
                baseline.linkTo(btn1Ref.baseline)
            }
    )
}
Related