Skip to content

Instantly share code, notes, and snippets.

@burkido
Created March 23, 2024 15:04
Show Gist options
  • Save burkido/d01b3695b90e1998a414d45cd53a0fe1 to your computer and use it in GitHub Desktop.
Save burkido/d01b3695b90e1998a414d45cd53a0fe1 to your computer and use it in GitHub Desktop.
/**
* Composable function that creates a text with clickable annotations.
*
* @param text The text that will be displayed. It should contain tags that match the tags in the annotations list.
* @param textStyle The style that will be applied to the text. If not provided, the default style is `MaterialTheme.typography.titleSmall`.
* @param stringsAnnotations A list of `LinkAnnotation` objects. Each `LinkAnnotation` contains a tag, an annotation, and a style. The tag is a substring of the text that will be annotated. The annotation is the actual annotation that will be attached to the tag in the text. The style is the style that will be applied to the text span that matches the tag.
* @param onClick A function that will be called when a text span with an annotation is clicked. The function takes the annotation as a parameter.
*/
@Composable
fun ClickableLocalizedText(
text: String,
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
stringsAnnotations: List<StringAnnotation>,
onClick: (String) -> Unit
) {
// Build an annotated string from the text and the annotations.
val annotatedString =
buildAnnotatedString {
append(text)
stringsAnnotations.forEach { stringAnnotation ->
val startIndex = text.indexOf(stringAnnotation.tag)
val endIndex = startIndex + stringAnnotation.tag.length
addStyle(
style = stringAnnotation.style,
start = startIndex,
end = endIndex
)
addStringAnnotation(
tag = stringAnnotation.tag,
annotation = stringAnnotation.annotation,
start = startIndex,
end = endIndex
)
}
}
ClickableText(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
text = annotatedString,
style = textStyle,
onClick = { position ->
stringsAnnotations.forEach { annotation ->
annotatedString
.getStringAnnotations(annotation.tag, position, position)
.firstOrNull()?.let { stringAnnotation ->
onClick.invoke(stringAnnotation.item)
return@forEach
}
}
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment