5

Currently I get this:

enter image description here

But I want something like this:

enter image description here

But also the text from "50" and "min" should be aligned to the top.

My code:

Row(verticalAlignment = Alignment.Bottom) {
    Text(
        text = "18",
        color = MaterialTheme.colors.primaryVariant,
        fontSize = 60.sp,
        modifier = Modifier
            .weight(1f).height(62.dp),
        textAlign = TextAlign.End,
    )
    Text(
        text = "hrs",
        modifier = Modifier.weight(1f).height(16.dp),
    )
}
Row(verticalAlignment = Alignment.Top) {
    Text(
        text = "50",
        color = MaterialTheme.colors.primaryVariant,
        fontSize = 28.sp,
        modifier = Modifier.weight(1f).height(30.dp).align(Alignment.Top),
        textAlign = TextAlign.End,
    )
    Text("min", modifier = Modifier.weight(1f))
}

As you see in my code I solved that by using the height property currently. But it doesn't work for the align top and it feels a bit wrong. is there a better way to make it work?

Daniel Däschle
  • 766
  • 10
  • 32

3 Answers3

6

You can use the AnnotatedString to display the text with multiple styles.

Something like:

Row() {
    Text(
        text = buildAnnotatedString {
        withStyle(style = SpanStyle(
            color = MaterialTheme.colors.primaryVariant,
            fontSize = 60.sp)) {
            append("18")
        }
        append(" hrs ")
    })
}

enter image description here

For the second case you can apply a BaselineShift to the min text:

Row() {
    Text(
        text = buildAnnotatedString {
            withStyle(style = SpanStyle(
                color = MaterialTheme.colors.primaryVariant,
                fontSize = 28.sp)) {
                append("50")
            }
            withStyle(style = SpanStyle(
                baselineShift = BaselineShift(+0.65f))) {
                append(" min ")
            }

        })
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
2

You can use AlignmentLine.LastBaseLine to properly size and position you're Text. You can do something like this:

Modifier.layout { measurable, constraints ->
    // Measure the composable
    val placeable = measurable.measure(constraints)

    // Check the composable has a LastBaseline
    check(placeable[LastBaseline] != AlignmentLine.Unspecified)
    val lastBaseline = placeable[LastBaseline]

    val placeableY = placeable.height - lastBaseline
    val height = placeable.height - placeableY

    layout(placeable.width, height) {
        placeable.placeRelative(0, -placeableY)
    }
}

If you want to completely remove even the bottom FirstBaseLine just subtract it to the height and that should do it.

Archie G. Quiñones
  • 11,638
  • 18
  • 65
  • 107
0

From version 1.2.0-alpha05, includeFontPadding is turned off as they announced: (https://developer.android.com/jetpack/androidx/releases/compose-ui#1.2.0-alpha05)

Text: includeFontPadding is now turned off by default. The clipping issues as a result of includeFontPadding=false is handled and no clipping should occur for tall scripts.

In case you haven't found the right solution. You can try this:

Text(text = buildAnnotatedString{
  withStyle(style = 
    ParagraphStyle(
      platformStyle = PlatformParagraphStyle(includeFontPadding = false),
      lineHeightStyle = LineHeightStyle(
        LineHeightStyle.Alignment.Bottom,
        LineHeightStyle.Trim.Both
      )
    )
  ){
        append("18")
    }
})