Home > Software engineering >  Align Image with Text baseline in a Row
Align Image with Text baseline in a Row

Time:09-17

How can I align an Image with a Text's baseline in a Row. Modifier.alignByBaseline() works for the Texts but the Image doesn't participate in the alignment.

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

enter image description here

CodePudding user response:

alignByBaseline aligns item by it's own baseline, not neighbours ones.

You can use paddingFromBaseline for Text and same value for image padding with verticalAlignment = Alignment.Bottom.

And to get actual value of baseline offset to pass it to the padding modifier, you need to wait for TextLayoutResult: it gets called when text layout is calculated depending on text size, font, etc.

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

  • Related