Created
September 6, 2023 20:01
-
-
Save nirbhayph/8600645d403c7acc671f056dfc4fdb95 to your computer and use it in GitHub Desktop.
Composing AnnotatedString - Poetry, Music, Code, Blogs, Expandables and Beyond
This file contains hidden or 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 AbstractArtText(){ | |
val abstractArtText = buildAnnotatedString { | |
withStyle(style = SpanStyle(fontSize = 42.sp, brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue, Color.Green)))) { | |
append("Colors in Motion") | |
} | |
append("\n\n") | |
append("Vivid shades of ") | |
withStyle(style = SpanStyle(brush = Brush.verticalGradient(listOf(Color.Magenta, Color.Yellow)))) { | |
append("passion") | |
} | |
append(" blend with the ") | |
withStyle(style = SpanStyle(brush = Brush.horizontalGradient(listOf(Color.Blue, Color.Green)))) { | |
append("calmness") | |
} | |
append(" of an eternal ") | |
withStyle(style = SpanStyle(brush = Brush.radialGradient(listOf(Color.Red, Color.Magenta)))) { | |
append("sunrise") | |
} | |
append(". A symphony of ") | |
withStyle(style = SpanStyle(brush = Brush.linearGradient(listOf(Color.Blue, Color.Cyan)))) { | |
append("colors") | |
} | |
append(" dances in the ") | |
withStyle(style = SpanStyle(brush = Brush.sweepGradient(listOf(Color.Green, Color.Blue, Color.Magenta)))) { | |
append("sky") | |
} | |
append(" like a dream.") | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = abstractArtText) | |
} | |
} |
This file contains hidden or 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 BasicStyles(){ | |
val boldText = buildAnnotatedString { | |
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { | |
append("Bold Text") | |
} | |
append("\n\n") | |
append("Regular Text") | |
} | |
val colorfulText = buildAnnotatedString { | |
withStyle(style = SpanStyle(color = Color.Red)) { | |
append("Vibrant Text") | |
} | |
append("\n\n") | |
append("Regular Text") | |
} | |
val highlightedText = buildAnnotatedString { | |
withStyle(style = SpanStyle(background = Color.Yellow)) { | |
append("Highlighted Text") | |
} | |
append("\n\n") | |
append("Regular Text") | |
} | |
} |
This file contains hidden or 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 BlogPost(){ | |
val blogPost = buildAnnotatedString { | |
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, fontSize = 28.sp)) { | |
append("Title of the Blog Post") | |
} | |
append("\n\n") | |
withStyle(style = SpanStyle(fontSize = 24.sp, fontStyle = FontStyle.Italic)) { | |
append("Introduction") | |
} | |
append("\nLorem ipsum dolor sit amet, consectetur adipiscing elit. ") | |
withStyle(style = SpanStyle(fontStyle = FontStyle.Italic, color = Color.Gray)) { | |
append("\nPhoto by John Doe") | |
} | |
append("\n\n") | |
withStyle(style = SpanStyle(Color.Red)) { | |
append("Quote of the Day\n") | |
} | |
append("\"The only way to do great work is to love what you do.\" - Steve Jobs") | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = blogPost) | |
} | |
} |
This file contains hidden or 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 LinkedText(){ | |
val annotatedLinkString: AnnotatedString = buildAnnotatedString { | |
val str = "Let's open google!" | |
val startIndex = str.indexOf("google") | |
val endIndex = startIndex + 6 | |
append(str) | |
addStyle( | |
style = SpanStyle( | |
color = Color.Red, | |
textDecoration = TextDecoration.Underline | |
), start = startIndex, end = endIndex | |
) | |
addUrlAnnotation( | |
UrlAnnotation("https://google.com"), | |
start = startIndex, | |
end = endIndex | |
) | |
} | |
val uriHandler = LocalUriHandler.current | |
ClickableText( | |
modifier = Modifier.padding(20.dp).fillMaxWidth(), | |
text = annotatedLinkString, | |
onClick = { | |
annotatedLinkString | |
.getUrlAnnotations(it, it) | |
.firstOrNull()?.let { annotation -> | |
uriHandler.openUri(annotation.item.url) | |
} | |
} | |
) | |
} |
This file contains hidden or 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 Code(){ | |
val codeEditorText = buildAnnotatedString { | |
append("fun ") | |
withStyle(style = SpanStyle(color = Color.Blue)) { | |
append("main") | |
} | |
append("() {\n") | |
append("\t") | |
withStyle(style = SpanStyle(color = Color.Green)) { | |
append("// Print \"Hello, World!\"") | |
} | |
append("\n") | |
append("\t") | |
withStyle(style = SpanStyle(color = Color.Blue)) { | |
append("println") | |
} | |
append("(") | |
withStyle(style = SpanStyle(color = Color.Red)) { | |
append("\"Hello, World!\"") | |
} | |
append(")\n") | |
append("}") | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = codeEditorText) | |
} | |
} |
This file contains hidden or 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 ExpandableText(){ | |
// Define tags for expanded and minified text | |
val tagExpanded = "expanded_text" | |
val tagMinified = "minified_text" | |
// Maintain the state of text toggling (expanded or minified) | |
val textToggleState = remember { mutableStateOf(Pair(tagMinified, "Read more ...")) } | |
// Create the annotated string for expanded and minified text | |
val expandedTextString: AnnotatedString = buildAnnotatedString { | |
val toggleString = textToggleState.value.second | |
// Define the base article snippet with a toggle string | |
val snippet = "In a groundbreaking discovery, scientists " + | |
"have identified a new species of marine life " + | |
"in the deep sea. $toggleString" | |
// Find the start and end indices of the toggle string | |
val startIndex = snippet.indexOf(toggleString) | |
val endIndex = startIndex + toggleString.length | |
// Apply styling to the entire snippet (font size and semi-bold) | |
withStyle(style = SpanStyle(fontSize = 24.sp)) { | |
withStyle(style = SpanStyle(fontWeight = FontWeight.SemiBold)) { | |
append(snippet) | |
} | |
// If the text is expanded, add more article content | |
if(textToggleState.value.first == tagExpanded) { | |
append( | |
"\n\nThis new species, tentatively named " + | |
"'DeepSea Marvel,' was found at a depth " + | |
"of 4,000 meters beneath the ocean's surface." | |
) | |
} | |
} | |
// Apply styling to the specified range (magenta color and underline) | |
addStyle( | |
style = SpanStyle( | |
color = Color.Magenta, | |
textDecoration = TextDecoration.Underline | |
), start = startIndex, end = endIndex | |
) | |
// Add annotations based on the text state (expanded or minified) | |
if(textToggleState.value.first == tagExpanded) { | |
addStringAnnotation( | |
tagMinified, | |
"Read again ...", | |
start = startIndex, | |
end = endIndex | |
) | |
} else { | |
addStringAnnotation( | |
tagExpanded, | |
"Show less ...", | |
start = startIndex, | |
end = endIndex | |
) | |
} | |
} | |
// Create a clickable text composable to display the article text | |
ClickableText( | |
modifier = Modifier.padding(16.dp).fillMaxWidth(), | |
text = expandedTextString, | |
onClick = { | |
// Toggle between expanded and minified text based on annotations | |
expandedTextString | |
.getStringAnnotations(it, it) | |
.firstOrNull()?.let { annotation -> | |
if(annotation.tag == tagExpanded) { | |
textToggleState.value = Pair(tagExpanded, annotation.item) | |
} else { | |
textToggleState.value = Pair(tagMinified, annotation.item) | |
} | |
} | |
} | |
) | |
} |
This file contains hidden or 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 MusicalNotation(){ | |
val musicalNotation = buildAnnotatedString { | |
withStyle(style = SpanStyle(fontSize = 24.sp, color = Color.Black)) { | |
append("Sheet Music") | |
} | |
append("\n\n") | |
withStyle(style = SpanStyle(fontSize = 36.sp, color = Color.Black)) { | |
append("♪") | |
} | |
append(" ") | |
withStyle(style = SpanStyle(fontSize = 20.sp, color = Color.Gray)) { | |
append("Piano Sonata in C Minor") | |
} | |
append("\n") | |
withStyle(style = SpanStyle(fontSize = 24.sp, color = Color.Black)) { | |
append("pp") | |
} | |
append(" ") | |
withStyle(style = SpanStyle(fontSize = 18.sp, color = Color.Gray)) { | |
append("Softly") | |
} | |
append(" ") | |
withStyle(style = SpanStyle(fontSize = 28.sp, color = Color.Black)) { | |
append("f") | |
} | |
append(" ") | |
withStyle(style = SpanStyle(fontSize = 18.sp, color = Color.Gray)) { | |
append("Loudly") | |
} | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = musicalNotation) | |
} | |
} |
This file contains hidden or 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 LegalLetterText(text: String) { | |
val customLineSpacingText = buildAnnotatedString { | |
// Apply paragraph style for custom line spacing using withStyle | |
withStyle( | |
style = ParagraphStyle( | |
lineHeight = 30.sp, | |
textAlign = TextAlign.Justify, | |
) | |
) { | |
append("Contrary to popular belief, Lorem Ipsum is not simply " + | |
"random text. It has roots in a piece of classical " + | |
"Latin literature from 45 BC, making it over 2000 years old. " + | |
"Richard McClintock, a Latin professor at Hampden-Sydney " + | |
"College in Virginia, looked up one of the more obscure Latin words," + | |
" consectetur, from a Lorem Ipsum passage, and going through the " + | |
"cites of the word in classical literature, discovered the" + | |
" undoubtable source. Lorem Ipsum comes from sections 1.10.32 " + | |
"and 1.10.33 of de Finibus Bonorum et Malorum " + | |
"(The Extremes of Good and Evil) by Cicero, written in 45 BC. " + | |
"This book is a treatise on the theory of ethics, very " + | |
"popular during the Renaissance. The first line of Lorem Ipsum, " + | |
"Lorem ipsum dolor sit amet.., comes from a line in section 1.10.32." + | |
"The standard chunk of Lorem Ipsum used since the 1500s is " + | |
"reproduced below for those interested. Sections 1.10.32 and 1.10.33 from " + | |
"de Finibus Bonorum et Malorum by Cicero are also reproduced in their exact" + | |
" original form, accompanied by English versions from the 1914 translation by H. Rackham.") | |
} | |
} | |
Text( | |
text = customLineSpacingText, | |
modifier = Modifier.fillMaxWidth().padding(16.dp), | |
) | |
} |
This file contains hidden or 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 StylizedPoetry(){ | |
val stylizedPoetry = buildAnnotatedString { | |
withStyle(style = SpanStyle(fontSize = 24.sp)) { | |
append("The ") | |
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Red)) { | |
append("rose") | |
} | |
append(" is ") | |
withStyle(style = SpanStyle(fontStyle = FontStyle.Italic, color = Color.Green)) { | |
append("red") | |
} | |
append("\n") | |
withStyle(style = SpanStyle(textDecoration = TextDecoration.LineThrough, color = Color.Blue)) { | |
append("The ") | |
} | |
withStyle(style = SpanStyle(fontStyle = FontStyle.Italic, color = Color.Red)) { | |
append("violets") | |
} | |
append(" are blue") | |
} | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = stylizedPoetry) | |
} | |
} |
This file contains hidden or 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 TerminalText(){ | |
val terminalText = buildAnnotatedString { | |
withStyle(style = SpanStyle(color = Color.Green)) { | |
append("user@android:~$") | |
} | |
append(" ls\n") | |
withStyle(style = SpanStyle(color = Color.Gray)) { | |
append("file1.txt file2.txt folder1\n") | |
} | |
withStyle(style = SpanStyle(color = Color.Green)) { | |
append("user@android:~$") | |
} | |
append(" cd folder1\n") | |
withStyle(style = SpanStyle(color = Color.Red)) { | |
append("cd: folder1: permission denied\n") | |
} | |
} | |
Box( | |
modifier = Modifier.fillMaxSize().padding(20.dp), | |
contentAlignment = Alignment.TopCenter, | |
) { | |
Text(text = terminalText) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment