Jetpack Compose 中的布局如何工作以及它们与 XML 有何关系?

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

我有一些文字。 我想让它在屏幕上居中。 我正在使用 Jetpack Compose。 我该怎么做呢? 我知道Jetpack Compose中有三种布局。

我应该使用哪一个? 我不知道布局是如何工作的。 它们是否像 XML 那样默认全屏显示? 如果是这样,我如何定位像 ConstraintLayout 这样的元素? 如何仅从一侧设置填充和边距以及如何设置 link 个元素?

我想如果您按照 Compose Pathway 进行操作,您的所有问题都可以得到澄清。但我会尽力为您总结...

您可以使用以下“布局管理器”之一(在 Compose 中称为布局)来组织您的组件:

  • Column(类似于垂直方向的 LinearLayout
  • Row(类似于水平方向的 LinearLayout
  • Box(类似于FrameLayout
  • ConstraintLayout。 如果您需要不同的东西,您可以使用 Layout 可组合项创建自定义布局。

“我应该使用哪一个?” 您可以根据情况使用其中任何一种...要简单地在屏幕中央显示文本,您可以使用所有这些来实现。

使用Column:

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

使用Box

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

“它们是否像 XML 中那样默认全屏显示?” 不,默认情况下它们是“wrap_content”。

“如何定位 ConstraintLayout 等元素?如何仅从一侧设置填充和边距以及如何 link 元素?” 您需要声明对组件的引用,然后相应地定位它们。

这是一个简单的例子...

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)
            }
    )
}