Skip to content

Instantly share code, notes, and snippets.

@albertogarrido
Forked from stevdza-san/HyperlinkText.kt
Last active March 28, 2023 15:04
Show Gist options
  • Save albertogarrido/3e8b56aa7e2affd85d253678c231a060 to your computer and use it in GitHub Desktop.
Save albertogarrido/3e8b56aa7e2affd85d253678c231a060 to your computer and use it in GitHub Desktop.
Embedd a Hyperlink within a Text using Jetpack Compose.
import androidx.compose.foundation.text.ClickableText
import androidx.compose.runtime.Composable
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.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.TextUnit
@Composable
fun HyperlinkText(
modifier: Modifier = Modifier,
fullText: String,
linkText: List<String>,
linkTextColor: Color = Color.Blue,
linkTextFontWeight: FontWeight = FontWeight.Medium,
linkTextDecoration: TextDecoration = TextDecoration.Underline,
hyperlinks: List<String> = listOf("https://stevdza-san.com"),
fontSize: TextUnit = TextUnit.Unspecified
) {
val annotatedString = buildAnnotatedString {
append(fullText)
linkText.forEachIndexed { index, link ->
val startIndex = fullText.indexOf(link)
val endIndex = startIndex + link.length
addStyle(
style = SpanStyle(
color = linkTextColor,
fontSize = fontSize,
fontWeight = linkTextFontWeight,
textDecoration = linkTextDecoration
),
start = startIndex,
end = endIndex
)
addStringAnnotation(
tag = "URL",
annotation = hyperlinks[index],
start = startIndex,
end = endIndex
)
}
addStyle(
style = SpanStyle(
fontSize = fontSize
),
start = 0,
end = fullText.length
)
}
val uriHandler = LocalUriHandler.current
ClickableText(
modifier = modifier,
text = annotatedString,
onClick = {
annotatedString
.getStringAnnotations("URL", it, it)
.firstOrNull()?.let { stringAnnotation ->
uriHandler.openUri(stringAnnotation.item)
}
}
)
}
/// ALTERNATIVE WITH MAPS
Thanks for sharing the code, appreciate that.
I made it a bit more expressive using Maps
Usage
HyperlinkText(
fullText = "By using our services are agreeing to our\n" + "Terms and Privacy statement",
hyperLinks = mutableMapOf(
"Terms" to "https://google.com",
"Privacy statement" to "https://google.com"
),
textStyle = TextStyle(
textAlign = TextAlign.Center,
color = Gray
),
linkTextColor = Purple,
fontSize = 18.sp
)
New Implementation
@Composable
fun HyperlinkText(
modifier: Modifier = Modifier,
fullText: String,
hyperLinks: Map<String, String>,
textStyle: TextStyle = TextStyle.Default,
linkTextColor: Color = Color.Blue,
linkTextFontWeight: FontWeight = FontWeight.Normal,
linkTextDecoration: TextDecoration = TextDecoration.None,
fontSize: TextUnit = TextUnit.Unspecified
) {
val annotatedString = buildAnnotatedString {
append(fullText)
for((key, value) in hyperLinks){
val startIndex = fullText.indexOf(key)
val endIndex = startIndex + key.length
addStyle(
style = SpanStyle(
color = linkTextColor,
fontSize = fontSize,
fontWeight = linkTextFontWeight,
textDecoration = linkTextDecoration
),
start = startIndex,
end = endIndex
)
addStringAnnotation(
tag = "URL",
annotation = value,
start = startIndex,
end = endIndex
)
}
addStyle(
style = SpanStyle(
fontSize = fontSize
),
start = 0,
end = fullText.length
)
}
val uriHandler = LocalUriHandler.current
ClickableText(
modifier = modifier,
text = annotatedString,
style = textStyle,
onClick = {
annotatedString
.getStringAnnotations("URL", it, it)
.firstOrNull()?.let { stringAnnotation ->
uriHandler.openUri(stringAnnotation.item)
}
}
)
}