19

I want to display a dynamic multiple lines text and an icon at the end of the last line. This icon can be animate. I try some ways but not success yet. How should I do?

Example view which had the same idea with my layout

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Quyết Vũ
  • 231
  • 1
  • 2
  • 6
  • you just want to add the icon or also want to animate the icon? – ked May 19 '21 at 15:20
  • 2
    Never needed it but there are placeholder for TextResults https://developer.android.com/reference/kotlin/androidx/compose/ui/text/TextLayoutInput#placeholders() Hope that might help you. Please answer your own question if you get it working. – 2jan222 May 19 '21 at 21:21
  • @ked I want both. – Quyết Vũ May 20 '21 at 02:30

1 Answers1

37

In the Text composable you can use the inlineContent to define a map of tags that replaces certain ranges of the text. It's used to insert composables into text layout.
Then using a Placeholder you can reserve space in text layout.

Something like:

val myId = "inlineContent"
val text = buildAnnotatedString {
    append("Where do you like to go?")
    // Append a placeholder string "[icon]" and attach an annotation "inlineContent" on it.
    appendInlineContent(myId, "[icon]")
}

val inlineContent = mapOf(
    Pair(
        // This tells the [CoreText] to replace the placeholder string "[icon]" by
        // the composable given in the [InlineTextContent] object.
        myId,
        InlineTextContent(
            // Placeholder tells text layout the expected size and vertical alignment of
            // children composable.
            Placeholder(
                width = 12.sp,
                height = 12.sp,
                placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
            )
        ) {
            // This Icon will fill maximum size, which is specified by the [Placeholder]
            // above. Notice the width and height in [Placeholder] are specified in TextUnit,
            // and are converted into pixel by text layout.
            
            Icon(Icons.Filled.Face,"",tint = Color.Red)
        }
    )
)

Text(text = text,
     modifier = Modifier.width(100.dp),
     inlineContent = inlineContent)

enter image description here

It is a composable so you can use your favorite animation.

Just an example:

var blue by remember { mutableStateOf(false) }
val color by animateColorAsState(if (blue) Blue else Red,
    animationSpec = tween(
        durationMillis = 3000
    ))

and change the Icon to

Icon(Icons.Filled.Face,"", tint = color)

enter image description here

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