Android 撰写时如何使文本垂直居中?

Joe*_*Dow 45 android text vertical-alignment android-jetpack-compose

我正在开发我的第一个完全由 Compose 设计的应用程序。

我需要使用Text()撰写组件垂直居中文本。在传统的 Android 开发实践中,我是通过对齐属性来实现这一点的。Text()compose 也具有对齐属性,但目前它的容量有限(Alignment.Horizontal()仅允许),尽管我Text()在 web 中进行研究时注意到不同的对齐值。类似的情况Column()- 它也具有对齐属性.wrapContentSize(),并且对此处可以使用的值也有限制,尽管网络上的快速研究表明它CenterVertically也可能会收到。

你是用什么方法来达到这种视觉效果的?完整的代码片段如下

@ExperimentalUnitApi
@Composable
fun TripBookingContent(state: PassengerTripUiState.TripBookUiState) {
    Log.d(App.TAG, "[screen] TripBookingContent")
    val baselineGrid = dimensionResource(id = R.dimen.baseline_grid)
    val mainPadding = dimensionResource(id = R.dimen.main_margin_compact)
    var componentSpace = dimensionResource(id = R.dimen.component_space)
    Column(
        modifier = Modifier
            .wrapContentHeight()
            .fillMaxWidth()
            .padding(
                paddingValues = PaddingValues(
                    horizontal = mainPadding,
                    vertical = baselineGrid
                )
            )
    ) {
        TripViewItem(
            data = state.trip,
            {},
            modifier = Modifier.padding(vertical = baselineGrid)
        )
        Text(
            text = stringResource(id = R.string.booking_screen_driver),
            color = colorResource(id = R.color.white),
            style = TextStyle(textIndent = TextIndent(firstLine = TextUnit(16F, TextUnitType.Sp))),
            modifier = Modifier
                .height(componentSpace)
                .padding(start = baselineGrid)
                .fillMaxWidth()
                .background(color = colorResource(id = R.color.design_default_color_secondary_variant))
        )
        Log.d(App.TAG, "[state] state.driver - ${state}")
        Log.d(App.TAG, "[state] state.driver.toDriver() - ${state.driver}")
        DriverCardContent(data = state.driver)

        Text(
            text = stringResource(id = R.string.booking_screen_msg),
            color = colorResource(id = R.color.white),
            style = TextStyle(textIndent = TextIndent(firstLine = TextUnit(16F, TextUnitType.Sp))),
            textAlign = TextAlign.Center,
            modifier = Modifier
//                .height(componentSpace)
                .height(32.dp)
                .padding(start = baselineGrid)
                .fillMaxWidth()
                .background(color = colorResource(id = R.color.colorPrimaryDark))
        )
        /**
         * Disable book button at current (alfa version), for more details
         * */
        Button(
            onClick = { /* no op */ },
            modifier = Modifier
                .alpha(0F)
                .fillMaxWidth()
                .padding(baselineGrid)
                .height(dimensionResource(id = R.dimen.button_height)),
            colors = ButtonDefaults.buttonColors(
                backgroundColor = Color.Blue,
                contentColor = Color.White
            ),
        ) {
            Text(
                text = stringResource(id = R.string.booking_screen_confirm_button),
                modifier = Modifier.align(Alignment.CenterVertically),
                fontWeight = FontWeight.Bold
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新我的最终解决方案如下。我必须将填充和背景移动到 Box() 层,以实现垂直和水平居中的文本。

        Box(
            contentAlignment = Alignment.Center,
            modifier = Modifier
                .height(32.dp)
                .padding(start = baselineGrid)
                .fillMaxWidth()
                .background(color = colorResource(id = R.color.colorPrimaryDark))
        ) {
            Text(
                text = stringResource(id = R.string.booking_screen_msg),
                color = colorResource(id = R.color.white),
                style = TextStyle(textIndent = TextIndent(firstLine = TextUnit(16F, TextUnitType.Sp))),
                textAlign = TextAlign.Center,
/*                modifier = Modifier
//                .height(componentSpace)
                    .height(32.dp)
                    .padding(start = baselineGrid)
                    .fillMaxWidth()
                    .background(color = colorResource(id = R.color.colorPrimaryDark))*/
            )
        } 
Run Code Online (Sandbox Code Playgroud)

小智 55

例如,如果您的文本小部件具有高度修饰符,则可以将文本垂直居中 - 例如,Text(text="example", modifier=Modifier.height(100.dp)您可以使用wrapContentHeight修饰符垂直对齐文本

Text(
    text = "Example",
    modifier = Modifier.width(100.dp)
        .height(100.dp)
        .background(color = Color.Cyan)
        .wrapContentHeight(align = Alignment.CenterVertically),
    color = Color.Black,
    fontSize = 42.sp,
    textAlign = TextAlign.Right
)
Run Code Online (Sandbox Code Playgroud)

  • 空的“wrapContentSize”就像一个魅力 (3认同)

Thr*_*ian 38

这可以通过多种方式来完成。正如您可以使用的其他答案中提到的Modifier.wrapContentSize()Modifier.layout这与wrappContentSize修饰符的实现方式非常相似,这就是大小修饰符的实现方式,它们基本上更改、更新或限制约束并测量和布局其内容。

Modifier.wrapContentSize将最小宽度和高度更改为 0,因此您将能够测量该范围内的内容,而不是返回固定最小、最大宽度范围的大小修饰符或约束。如min=200.dp,max=200.dp。如果将最小范围更改为 0,您的内容将使用其实际内容尺寸进行测量,并将其放置在任何对齐方式中。

@Preview
@Composable
private fun Test() {
    Text(
        text = "Hello world",
        modifier = Modifier
            .border(2.dp, Color.Red)
            .size(200.dp)
            .layout { measurable, constraints ->
                val placeable =
                    measurable.measure(
                        // This is how wrapContent works
                        constraints.copy(minWidth = 0, minHeight = 0)
                    )
                layout(constraints.maxWidth, constraints.maxHeight) {
                 // This is how wrapContent alignment works
                    val x = (constraints.maxWidth - placeable.width) / 2
                    val y = (constraints.maxHeight - placeable.height) / 2
                    placeable.placeRelative(x, y)
                }
            },
        textAlign = TextAlign.Center
    )
} 
Run Code Online (Sandbox Code Playgroud)

Box()与 一起使用contentAlignment = Alignment.Center。还有用于对齐的 CenterStart 和 CenterEnd 选项。

   Box(
        contentAlignment = Alignment.Center,
    ) {
        Text(
            text = "Text",
            textAlign = TextAlign.Center
        )
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用 cmd/crtl + 单击单击“Card”,您将看到 Card 源是一个“Surface”,而 Surface 本身也是一个带有“contentAlignment: Alignment = Alignment.TopStart”的 Box。因此,可以使用 Box,或者您可以使用“布局”创建自己的可组合项,并根据您的需要使用位置。如果您有兴趣,我有关于布局和许多其他内容的教程。 (2认同)
  • 使用自定义“布局”和“修改器”,您可以拥有自己的对齐方案,如下图所示[图片](https://github.com/SmartToolFactory/Jetpack-Compose-Tutorials/blob/master/screenshots/tutorial3_3_1.png) (2认同)

Nag*_*obi 8

对齐修饰符取决于父级,这就是它应该的样子,在垂直列表(列)中,垂直对齐由父级处理(这很好,compose 可以强制执行此操作)

因此,在您的情况下,您可能需要不同的层次结构。例如:Box而不是Column. 或者,您可以调整 的大小,例如Text将其设置为高度,然后使用, 将其文本居中。200dptextAlign

以供参考:

  • Box(contentAlignment = Alignment.Center)-> 指定子项的对齐方式
  • Text(text = "example", modifier = Modifier.wrapContentSize().align())-> 指定Text父级下可组合项的对齐方式
  • Text(text = "example", textAlign = TextAlign.Center)-> 指定可组合项内部文本的对齐方式,使用它wrapContentSize()不会产生任何效果,因为可组合项的大小与其内容文本相同