The AnnotatedString text container widget differs from the standard Text widget in Compose Multiplatform. It aims to create rich, multiple-style text within a single Text widget. In today’s tutorial, we will integrate multiple-style text and clickable text with a custom URL link and apply different text styles on the part of the text.
KMP AnnotatedString Creating Multi Style Clickable Text with Link
Start Coding for the app:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
@Composable fun MultipleStyleTextWithLink() { val uriHandler = LocalUriHandler.current val annotatedText = buildAnnotatedString { append("Discover more on ") // Add styled clickable text pushStringAnnotation(tag = "URL", annotation = "https://kotlinguide.com") withStyle( style = SpanStyle( color = Color.Blue, textDecoration = TextDecoration.Underline ) ) { append("KotlinGuide") } pop() append(" for detailed tutorials.") withStyle(style = SpanStyle(background = Color.Yellow)) { append("This is Highlighted Text") } append("\n") withStyle(style = SpanStyle(color = Color.Red)) { append("Colored Text") } } Text( text = annotatedText, modifier = Modifier .padding(16.dp) .clickable { annotatedText.getStringAnnotations( tag = "URL", start = 0, end = annotatedText.length ) .firstOrNull()?.let { annotation -> uriHandler.openUri(annotation.item) } }, ) } |
Code explanation:
- LocalUriHandler.current: It retrieves a URI handler to open your custom URL in the device’s default browser application.
- buildAnnotatedString { append(“Your Text”)}: Create a AnnotatedString widget. The append property adds part of the text to our custom string one after another.
- pushStringAnnotation: The tag property defines this string as a URL string, and then the annotation will be used to assign a URL.
- withStyle: To apply a custom Style on that particular part of the text.
- pop(): End the current context. So, the style applied to this section will not be applied to incoming append text.
Complete source code for App.kt file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
package com.app.test import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp @Composable fun App() { MaterialTheme { Column( modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(8.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { MultipleStyleTextWithLink() } } } @Composable fun MultipleStyleTextWithLink() { val uriHandler = LocalUriHandler.current val annotatedText = buildAnnotatedString { append("Discover more on ") // Add styled clickable text pushStringAnnotation(tag = "URL", annotation = "https://kotlinguide.com") withStyle( style = SpanStyle( color = Color.Blue, textDecoration = TextDecoration.Underline ) ) { append("KotlinGuide") } pop() append(" for detailed tutorials.") withStyle(style = SpanStyle(background = Color.Yellow)) { append("This is Highlighted Text") } append("\n") withStyle(style = SpanStyle(color = Color.Red)) { append("Colored Text") } } Text( text = annotatedText, modifier = Modifier .padding(16.dp) .clickable { annotatedText.getStringAnnotations( tag = "URL", start = 0, end = annotatedText.length ) .firstOrNull()?.let { annotation -> uriHandler.openUri(annotation.item) } }, ) } |
Screenshot in Android:
Screenshot in iOS: