将图像与一行中的文本基线对齐

Align Image with Text baseline in a Row

如何使图像与行中文本的基线对齐。 Modifier.alignByBaseline() 适用于文本,但图像不参与对齐。

@Composable
fun Sample() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.Center,
    ) {
        Text(
            text = "One",
            modifier = Modifier.alignByBaseline(),
            fontSize = 40.sp
        )
        Image(
            modifier = Modifier
                .padding(horizontal = 8.dp)
                .size(24.dp)
                .alignBy(FirstBaseline),
            painter = painterResource(id = R.drawable.ic_launcher_background),
            contentDescription = "",
        )
        Text(
            text = "two",
            modifier = Modifier.alignByBaseline(),
            fontSize = 40.sp
        )
    }
}

alignByBaseline 根据项目自身的基线而不是邻居的基线对齐项目。

您可以对 Text 使用 paddingFromBaseline,对图像 paddingverticalAlignment = Alignment.Bottom 使用相同的值。

要获取基线偏移的实际值以将其传递给填充修饰符,您需要等待 TextLayoutResult:根据文本大小、字体等计算文本布局时调用它

Row(
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.Bottom,
    modifier = Modifier.fillMaxWidth()
) {
    var maxBaseline by remember { mutableStateOf(0f) }
    fun updateMaxBaseline(textLayoutResult: TextLayoutResult) {
        maxBaseline = max(maxBaseline, textLayoutResult.size.height - textLayoutResult.lastBaseline)
    }
    val topBaselinePadding = with(LocalDensity.current) { maxBaseline.toDp() }
    Text(
        text = "One",
        modifier = Modifier.paddingFromBaseline(bottom = topBaselinePadding),
        fontSize = 20.sp,
        onTextLayout = ::updateMaxBaseline
    )
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_background),
        contentDescription = "",
        modifier = Modifier
            .padding(bottom = topBaselinePadding)
            .size(24.dp)
    )
    Text(
        text = "two",
        modifier = Modifier.paddingFromBaseline(bottom = topBaselinePadding),
        fontSize = 40.sp,
        onTextLayout = ::updateMaxBaseline
    )
}