Jetpack Compose 中的文本居中

3

我试图将Jetpack Compose中Text组件内的内容居中,但我没有成功。虽然我很新手,但代码看起来没问题。以下是代码:

Row(
        modifier = Modifier
            .padding(8.dp)
            .height(30.dp)
            .fillMaxHeight(),
    ) {
        IconButton(..) {..}
        Spacer(modifier = Modifier.width(4.dp))
        Text(
            text = "Some text",
            textAlign = TextAlign.Center,
            modifier = Modifier
                .fillMaxHeight()
                .border(1.dp, Color.Black, RoundedCornerShape(20))
                .width(120.dp)
                .background(color = Color.White, RoundedCornerShape(20))
                .align(Alignment.CenterVertically)
        )
        Spacer(modifier = Modifier.width(4.dp))
        IconButton(..) {..}
    }

这将产生以下结果:enter image description here
3个回答

5

根据你的修饰符,Text将占满整个高度,在这种情况下,.align(Alignment.Center)无法帮助你。

你可以将Text放在一个Box里,并在那里居中:

Row(
    modifier = Modifier
        .padding(8.dp)
        .height(30.dp)
        .fillMaxHeight()
) {
    IconButton({ }) { Text("hello ") }
    Spacer(modifier = Modifier.width(4.dp))
    Box(
        Modifier
            .fillMaxHeight()
            .border(1.dp, Color.Black, RoundedCornerShape(20))
            .width(120.dp)
            .background(color = Color.White, RoundedCornerShape(20))
    ) {
        Text(
            text = "Some text",
            textAlign = TextAlign.Center,
            modifier = Modifier
                .align(Alignment.Center)
        )
    }

    Spacer(modifier = Modifier.width(4.dp))
    IconButton({ }) { Text("hello ") }
}

您可以通过为文本添加填充来解决此问题,但在这种情况下,您无法明确指定 Row 高度,而需要让它自适应内容大小:

Row(
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier
        .padding(8.dp)
) {
    IconButton({ }) { Text("hello ") }
    Spacer(modifier = Modifier.width(4.dp))
    Text(
        text = "Some text",
        textAlign = TextAlign.Center,
        modifier = Modifier
            .border(1.dp, Color.Black, RoundedCornerShape(20))
            .width(120.dp)
            .background(color = Color.White, RoundedCornerShape(20))
            .padding(vertical = 10.dp)
    )
    Spacer(modifier = Modifier.width(4.dp))
    IconButton({ }) { Text("hello ") }
}


3
我理解你的做法,但这似乎是一个变通方法。在不使用其他Compose元素的情况下无法将_text_居中于Text中,这在我看来相当奇怪。 - daniyelp
@daniyelp 我增加了另一个选项,但你必须选择以下两种方式之一:使用Box将文本居中于边框内,或让你的Row根据内容大小自动换行。 - Phil Dukhov
1
第一个解决方案确实可以完成任务,但我告诉过你为什么我还不能接受这个答案。我认为第二个解决方案比第一个更像是一种变通方法,因为你必须硬编码填充。 - daniyelp
@daniyelp,请在您的问题中添加您想要实现的所有内容。他已经回答了您的问题。 - adwardwo1f
@daniyelp,你必须“硬编码”填充或高度,这不是某种反模式。如果你硬编码高度(就像你在代码中所做的那样),唯一的解决方案是将“Text”对齐到容器内部。 - Phil Dukhov

1
将其放在列中并居中两侧也可以起作用:
Column(
    modifier = Modifier
        .fillMaxHeight()
        .border(1.dp, Color.Black, RoundedCornerShape(20))
        .width(120.dp)
        .background(color = Color.White, RoundedCornerShape(20)),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text(text = "Some text")
}

enter image description here


-3
首先,Compose 在许多方面与 Android Views 不同。'View' 中没有 'C',但 'Composable' 以 'C' 开头。好的,现在基础知识已经清楚了,你会发现你观察到的行为确实是预期的。原因如下:
Composables(可组合项)和视图一样,有边界(将其与环境分离的四个角点),我们可以使用修饰符修改这些边界。包括要呈现的文本的 Composables,例如 Text 和所有的 TextField 遵循相同的基本原则。如果我将文本设置得非常大(比最大高度大四分之一),那么我这样做是因为我认为我的文本值要放置的位置很大,否则这样做就没有意义,对吧?因此,当您创建一个尺寸大于所需值的 Text 时,它应该被视为一个可组合的“准备好”容纳其所组成的最大容量。

好的,如果您想以居中的方式更改文本值,该怎么做呢?您可以添加换行符(按多次回车键),直到文本在垂直方向上看起来处于中间位置,但这只是很烦人的。如果您的值比填充 Comp 所需的尺寸小,那么您就不需要指定如此大的边界。假设一个人可以修改此值。每次值发生变化时,都需要根据字符串长度+字体大小+字体系列+字体样式来计算边缘空间。如果有更快的方法,为什么不采用呢?您可以使用名为 wrapContentHeight 的黄金修饰符。现在,它将异步地将 Composable 本身包裹在文本周围,限制所需的空间量。现在边界已经设置好了,您可以通过指定坐标在屏幕上任意位置放置 Composable。对于所需的行为,一些 Composables 提供了方便的 verticalAlignemnt 参数或类似的东西,它会自动异步地为您完成工作。

你可能会问为什么提供水平对齐,尽管具有相同的效果,我认为这是因为人们自打早期打字机时代就习惯了这种约定俗成。从内存和/或性能的角度来看,垂直对齐可能是低效的。

然而,如果由于某种奇怪的原因,您发誓不使用外部组件进行内容对齐,则我想实现自己版本的对齐器并不是什么大问题。只是垂直空间被分成固定宽度的“行”,在任何给定时间,文本值只能显示在特定的行上。因此,如果组合的高度不完全是线高的整数倍,那么放置块将会很棘手(实际上使用预构建的东西是不可能的)。例如,在您的情况下,组合似乎没有超过两个线高。现在要居中,您必须将其放置在1.5倍的行高处,这是Text无法实现的,因此换行实现将在此处失败。如果高度是线高的偶数倍,则对齐也不会完美。

这只是一团糟。


大致正确。 - Richard Onslow Roper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接