Created
September 16, 2022 21:27
-
-
Save slaviboy/2da32bbed556d2232a8d9dddd510c143 to your computer and use it in GitHub Desktop.
Jetpack Compose Text hyperlink some section of the text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class Highlight( | |
val text: String, | |
val data: String, | |
val onClick: (data: String) -> Unit | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun HighlightedText( | |
text: String, | |
highlights: List<Highlight>, | |
modifier: Modifier = Modifier, | |
) { | |
data class TextData( | |
val text: String, | |
val tag: String? = null, | |
val data: String? = null, | |
val onClick: ((data: AnnotatedString.Range<String>) -> Unit)? = null | |
) | |
val textData = mutableListOf<TextData>() | |
if (highlights.isEmpty()) { | |
textData.add( | |
TextData( | |
text = text | |
) | |
) | |
} else { | |
var startIndex = 0 | |
highlights.forEachIndexed { i, link -> | |
val endIndex = text.indexOf(link.text) | |
if (endIndex == -1) { | |
throw Exception("Highlighted text mismatch") | |
} | |
textData.add( | |
TextData( | |
text = text.substring(startIndex, endIndex) | |
) | |
) | |
textData.add( | |
TextData( | |
text = link.text, | |
tag = "${link.text}_TAG", | |
data = link.data, | |
onClick = { | |
link.onClick(it.item) | |
} | |
) | |
) | |
startIndex = endIndex + link.text.length | |
if (i == highlights.lastIndex && startIndex < text.length) { | |
textData.add( | |
TextData( | |
text = text.substring(startIndex, text.length) | |
) | |
) | |
} | |
} | |
} | |
val annotatedString = buildAnnotatedString { | |
textData.forEach { linkTextData -> | |
if (linkTextData.tag != null && linkTextData.data != null) { | |
pushStringAnnotation( | |
tag = linkTextData.tag, | |
annotation = linkTextData.data, | |
) | |
withStyle( | |
style = SpanStyle( | |
color = infoLinkTextColor | |
), | |
) { | |
append(linkTextData.text) | |
} | |
pop() | |
} else { | |
append(linkTextData.text) | |
} | |
} | |
} | |
ClickableText( | |
text = annotatedString, | |
style = TextStyle( | |
fontSize = 0.031.sw, | |
fontWeight = FontWeight.Normal, | |
color = infoTextColor, | |
textAlign = TextAlign.Start | |
), | |
onClick = { offset -> | |
textData.forEach { annotatedStringData -> | |
if (annotatedStringData.tag != null && annotatedStringData.data != null) { | |
annotatedString.getStringAnnotations( | |
tag = annotatedStringData.tag, | |
start = offset, | |
end = offset, | |
).firstOrNull()?.let { | |
annotatedStringData.onClick?.invoke(it) | |
} | |
} | |
} | |
}, | |
modifier = modifier | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivity : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContent { | |
HighlightedText( | |
text = stringResource(id = R.string.disclaimer), | |
highlights = listOf( | |
Highlight( | |
text = stringResource(id = R.string.privacy_policy), | |
data = "https://stackoverflow.com/legal/privacy-policy", | |
onClick = { link -> | |
// do something with link | |
} | |
), | |
Highlight( | |
text = stringResource(id = R.string.terms_of_use), | |
data = "https://stackoverflow.com/legal/terms-of-use", | |
onClick = { link -> | |
// do something with link | |
} | |
) | |
) | |
) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<resources> | |
<string name="disclaimer">By joining you agree to the privacy policy and terms of use.</string> | |
<string name="privacy_policy">privacy policy</string> | |
<string name="terms_of_use">terms of use</string> | |
</resources> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment