我正在开发我的第一个完全由 Compose 设计的应用程序。
我需要使用
Text()
撰写组件将文本垂直居中。在传统的 Android 开发实践中,我是通过对齐属性来实现这一点的。 Text()
compose 也具有对齐属性,但目前它的容量有限(仅允许使用 Alignment.Horizontal()
),尽管我在 web 中进行研究时注意到 Text()
中的对齐值不同。 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
)
}
}
}
更新 我的最终解决方案如下。我必须将填充和背景移动到 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))*/
)
}
这可以通过多种方式完成。正如其他答案中提到的,您可以使用
Modifier.wrapContentSize()
,Modifier.layout
,这与wrapContentSize修饰符的实现方式非常相似,这就是大小修饰符的实现方式,它们基本上更改、更新或限制约束并测量和布局其内容。
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
)
}
或将
Box()
与 contentAlignment = Alignment.Center
一起使用。还有用于对齐的 CenterStart 和 CenterEnd 选项。
Box(
contentAlignment = Alignment.Center,
) {
Text(
text = "Text",
textAlign = TextAlign.Center
)
}
如果您的文本小部件具有高度修饰符,则可以将文本垂直居中 -
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)
对齐修饰符取决于父级,这就是它应该的样子,在垂直列表(列)中,垂直对齐由父级处理(这很好,compose 可以强制执行此操作)
在您的情况下,您可能需要不同的层次结构。例如:
Box
而不是Column
。或者,您可以调整 Text
的大小,例如将其高度设为 200dp
,然后使用 textAlign
将其文本居中。
供参考:
Box(contentAlignment = Alignment.Center)
-> 指定子项的对齐方式Text(text = "example", modifier = Modifier.wrapContentSize().align())
-> 指定 Text
可组合项在父级Text(text = "example", textAlign = TextAlign.Center)
-> 指定可组合项内部文本的对齐方式,与 wrapContentSize()
一起使用不会产生任何效果,因为可组合项的大小与其内容文本相同