public class AnnotatedString internal constructor(
internal val annotations: List<Range<out Annotation>>?,
public val text: String,
) : CharSequence
Text with multiple styles.
SpanStyle applies character-level styling (such as color, font, or decorations) to a range of text. ParagraphStyle applies paragraph-level layout configuration (such as alignment, line height, or indent) to the entire paragraph.
Use Builder to construct.
Precedence and Merging Rules
When multiple SpanStyles are applied to overlapping ranges, they are merged character by character:
- Styles appearing later in the
spanStyleslist take precedence and overwrite matching - Any unspecified properties (such as
androidx.compose.ui.graphics.Color.Unspecifiedor
properties of earlier styles.
TextUnit.Unspecified) do not overwrite prior styles, retaining the value from the previous style in the stack or the default text style.
Paragraphs Arrangement
ParagraphStyles can be applied to parts of the text. However, paragraph ranges must not partially overlap. They can only be nested or fully overlapping. If ranges are invalid, an IllegalArgumentException is thrown.
Valid arrangements (nested or non-overlapping):
- Non-overlapping:
\[abc\](def)(two separate paragraphs) - Nested:
\abc(def)ghi\`(inner paragraph(def)nested inside outer\abc...ghi\`) - Fully overlapping:
\(abc)\``
Invalid arrangement (partial overlap):
- Overlapping:
\abc(def\ghi)(inner starts inside outer, but ends outside - invalid!)
Gaps between paragraph styles are filled with default styles. Nested paragraphs are split and merged with parent styles.
Properties
spanStyles
public val spanStyles: List<Range<SpanStyle>>
All SpanStyle that have been applied to a range of this String
paragraphStyles
public val paragraphStyles: List<Range<ParagraphStyle>>
All ParagraphStyle that have been applied to a range of this String
length
public override val length: Int
Creates an AnnotatedString with annotations.
Parameters
| text | text to display |
| annotations | annotations to apply to text. Overlapping SpanStyles merge (see AnnotatedString merging rules). ParagraphStyle ranges must follow paragraph arrangement rules (see AnnotatedString class documentation). |
Throws: IllegalArgumentException
if annotations contains invalid overlapping paragraph ranges
Functions
subSequence
public fun subSequence(range: TextRange): AnnotatedString
Return a substring for the AnnotatedString and include the styles in the given range.
Parameters
| range | the text range |
plus
public operator fun plus(other: AnnotatedString): AnnotatedString
getStringAnnotations
public fun getStringAnnotations(tag: String, start: Int, end: Int): List<Range<String>>
Query the string annotations attached on this AnnotatedString. Annotations are metadata attached on the AnnotatedString, for example, a URL is a string metadata attached on the a certain range. Annotations are also store with Range like the styles.
Parameters
| tag | the tag of the annotations that is being queried. It's used to distinguish the annotations for different purposes. |
| start | the start of the query range, inclusive. |
| end | the end of the query range, exclusive. |
Return
a list of annotations stored in Range. Notice that All annotations that intersect with the range start, end) will be returned. When [start is bigger than end, an empty list will be returned.
hasStringAnnotations
public fun hasStringAnnotations(tag: String, start: Int, end: Int): Boolean
Returns true if getStringAnnotations with the same parameters would return a non-empty list
getStringAnnotations
public fun getStringAnnotations(start: Int, end: Int): List<Range<String>>
Query all of the string annotations attached on this AnnotatedString.
Parameters
| start | the start of the query range, inclusive. |
| end | the end of the query range, exclusive. |
Return
a list of annotations stored in Range. Notice that All annotations that intersect with the range start, end) will be returned. When [start is bigger than end, an empty list will be returned.
getTtsAnnotations
public fun getTtsAnnotations(start: Int, end: Int): List<Range<TtsAnnotation>>
Query all of the TtsAnnotations attached on this AnnotatedString.
Parameters
| start | the start of the query range, inclusive. |
| end | the end of the query range, exclusive. |
Return
a list of annotations stored in Range. Notice that All annotations that intersect with the range start, end) will be returned. When [start is bigger than end, an empty list will be returned.
getUrlAnnotations
@Deprecated("Use LinkAnnotation API instead", ReplaceWith("getLinkAnnotations(start, end)"))
public fun getUrlAnnotations(start: Int, end: Int): List<Range<UrlAnnotation>>
Query all of the UrlAnnotations attached on this AnnotatedString.
Parameters
| start | the start of the query range, inclusive. |
| end | the end of the query range, exclusive. |
Return
a list of annotations stored in Range. Notice that All annotations that intersect with the range start, end) will be returned. When [start is bigger than end, an empty list will be returned.
getLinkAnnotations
public fun getLinkAnnotations(start: Int, end: Int): List<Range<LinkAnnotation>>
Query all of the LinkAnnotations attached on this AnnotatedString.
Parameters
| start | the start of the query range, inclusive. |
| end | the end of the query range, exclusive. |
Return
a list of annotations stored in Range. Notice that All annotations that intersect with the range start, end) will be returned. When [start is bigger than end, an empty list will be returned.
hasLinkAnnotations
public fun hasLinkAnnotations(start: Int, end: Int): Boolean
Returns true if getLinkAnnotations with the same parameters would return a non-empty list
hasEqualAnnotations
public fun hasEqualAnnotations(other: AnnotatedString): Boolean
Compare the annotations between this and another AnnotatedString.
This may be used for fast partial equality checks.
Note that this checks all annotations including spanStyles and paragraphStyles, but equals still may be false if text is different.
Parameters
| other | to compare annotations with |
Return
true if and only if this compares equal on annotations with other
mapAnnotations
public fun mapAnnotations(
transform: (Range<out Annotation>) -> Range<out Annotation>
): AnnotatedString
Returns a new AnnotatedString where a list of annotations contains the results of applying the given transform function to each element in the original annotations list.
flatMapAnnotations
public fun flatMapAnnotations(
transform: (Range<out Annotation>) -> List<Range<out Annotation>>
): AnnotatedString
Returns a new AnnotatedString where a list of annotations contains all elements yielded from results transform function being invoked on each element of original annotations list.
Members
Range
public data class Range<T>(
public val item: T,
public val start: Int,
public val end: Int,
public val tag: String,
)
The information attached on the text such as a SpanStyle.
Parameters
| item | The object attached to AnnotatedStrings. |
| start | The start of the range where item takes effect. It's inclusive |
| end | The end of the range where item takes effect. It's exclusive |
| tag | The tag used to distinguish the different ranges. It is useful to store custom data. And Ranges with same tag can be queried with functions such as getStringAnnotations. |
Builder
public class Builder public constructor(capacity: Int = 16) : Appendable
Builds an AnnotatedString incrementally.
Implements Appendable for compatibility with standard text APIs.
Parameters
| capacity | initial capacity for the internal buffer |
Properties
length
public val length: Int
Returns the length of the String.
Functions
append
public fun append(text: String)
Appends the given String to this Builder.
Parameters
| text | the text to append |
deprecatedappendreturning_void
@Deprecated(
message =
"Replaced by the append(Char) method that returns an Appendable. " +
"This method must be kept around for binary compatibility.",
level = DeprecationLevel.HIDDEN,
)
// Set the JvmName to preserve compatibility with bytecode that expects a void return type.
public fun deprecated_append_returning_void(char: Char)
append
public fun append(text: AnnotatedString)
Appends the given AnnotatedString to this Builder.
Parameters
| text | the text to append |
append
public fun append(text: AnnotatedString, start: Int, end: Int)
Appends the range of text between start (inclusive) and end (exclusive) to this Builder. All spans and annotations from text between start and end will be copied over as well.
Parameters
| text | the text to append |
| start | The index of the first character in text to copy over (inclusive). |
| end | The index after the last character in text to copy over (exclusive). |
addStyle
public fun addStyle(style: SpanStyle, start: Int, end: Int)
Applies style to the given range.
Parameters
| style | SpanStyle to apply |
| start | inclusive start offset |
| end | exclusive end offset |
addStyle
public fun addStyle(style: ParagraphStyle, start: Int, end: Int)
Applies style to the given range, creating a separate paragraph.
Paragraph ranges must follow paragraph arrangement rules. See AnnotatedString class documentation for details and examples.
Parameters
| style | ParagraphStyle to apply |
| start | inclusive start offset |
| end | exclusive end offset |
addStringAnnotation
public fun addStringAnnotation(tag: String, annotation: String, start: Int, end: Int)
Associates a string annotation with a range.
Parameters
| tag | tag to identify the annotation |
| annotation | string annotation value |
| start | inclusive start offset |
| end | exclusive end offset |
addTtsAnnotation
public fun addTtsAnnotation(ttsAnnotation: TtsAnnotation, start: Int, end: Int)
Set a TtsAnnotation for the given range defined by start and end.
Parameters
| ttsAnnotation | an object that stores text to speech metadata that intended for the TTS engine. |
| start | the inclusive starting offset of the range |
| end | the exclusive end offset of the range |
addUrlAnnotation
@Deprecated(
"Use LinkAnnotation API for links instead",
ReplaceWith("addLink(, start, end)"),
)
public fun addUrlAnnotation(urlAnnotation: UrlAnnotation, start: Int, end: Int)
Set a UrlAnnotation for the given range defined by start and end. URLs may be treated specially by screen readers, including being identified while reading text with an audio icon or being summarized in a links menu.
Parameters
| urlAnnotation | A UrlAnnotation object that stores the URL being linked to. |
| start | the inclusive starting offset of the range |
| end | the exclusive end offset of the range |
addLink
public fun addLink(url: LinkAnnotation.Url, start: Int, end: Int)
Associates a URL link with a range.
Clicking the text opens the URL using androidx.compose.ui.platform.UriHandler.
Screen readers present URLs in different ways, such as using a links menu or audio cues.
Parameters
| url | the target URL |
| start | inclusive start offset |
| end | exclusive end offset |
addLink
public fun addLink(clickable: LinkAnnotation.Clickable, start: Int, end: Int)
Associates a clickable link with a range.
Clicking the text triggers a LinkInteractionListener with clickable.
Screen readers present clickables in different ways, such as using a links menu or audio cues.
Parameters
| clickable | click metadata |
| start | inclusive start offset |
| end | exclusive end offset |
addBullet
public fun addBullet(bullet: Bullet, start: Int, end: Int)
Adds an annotation to draw a bullet. Unlike another overload, this one doesn't add a separate ParagraphStyle. As so for bullet to be rendered, make sure it starts on a separate line by adding a newline before or wrapping with a ParagraphStyle.
For a convenient API to create a bullet list check withBulletList.
Parameters
| bullet | a bullet to draw before the text |
| start | the inclusive starting offset of the range |
| end | the exclusive end offset of the range |
addBullet
public fun addBullet(bullet: Bullet, indentation: TextUnit, start: Int, end: Int)
Adds an annotation to draw a bullet together with a paragraph that adds an indentation.
Parameters
| bullet | a bullet to draw before the text |
| indentation | indentation that is added to the paragraph. Note that this indentation should be large enough to fit a bullet and a padding between the bullet and beginning of the paragraph |
| start | the inclusive starting offset of the range |
| end | the exclusive end offset of the range |
pushStyle
public fun pushStyle(style: SpanStyle): Int
Applies the given SpanStyle to any appended text until a corresponding pop is called.
Parameters
| style | SpanStyle to be applied |
pushStyle
public fun pushStyle(style: ParagraphStyle): Int
Applies the given ParagraphStyle to any appended text until a corresponding pop is called.
Parameters
| style | ParagraphStyle to be applied |
pushBullet
public fun pushBullet(bullet: Bullet): Int
Applies the given bullet annotation to any appended text until a corresponding pop is called. For bullet to be rendered, make sure it starts on a separate line by either adding a newline before or by wrapping with a ParagraphStyle.
For a convenient API to create a bullet list check withBulletList.
withBulletList
public fun <R : Any> withBulletList(
indentation: TextUnit = Bullet.DefaultIndentation,
bullet: Bullet = Bullet.Default,
block: BulletScope.() -> R,
): R
Creates a bullet list which allows to define a common indentation and a bullet for evey bullet list item created inside the list.
Note that when nesting the withBulletList calls, the indentation inside the nested list will be a combination of all indentations in the nested chain. For example,
withBulletList(10.sp) {
withBulletList(15.sp) {
// items indentation 25.sp
}
}
withBulletListItem
public fun <R : Any> BulletScope.withBulletListItem(
bullet: Bullet? = null,
block: Builder.() -> R,
): R
Creates a bullet list item around the content produced by the block. The list item creates a separate paragraph with the indentation to the bullet defined by the preceding Builder.withBulletList calls.
Parameters
| bullet | defines the bullet to be drawn |
| block | function to be executed |
pushStringAnnotation
public fun pushStringAnnotation(tag: String, annotation: String): Int
Attach the given annotation to any appended text until a corresponding pop is called.
Parameters
| tag | the tag used to distinguish annotations |
| annotation | the string annotation attached on this AnnotatedString |
pushTtsAnnotation
public fun pushTtsAnnotation(ttsAnnotation: TtsAnnotation): Int
Attach the given ttsAnnotation to any appended text until a corresponding pop is called.
Parameters
| ttsAnnotation | an object that stores text to speech metadata that intended for the TTS engine. |
pushUrlAnnotation
@Deprecated(
"Use LinkAnnotation API for links instead",
ReplaceWith("pushLink(, start, end)"),
)
public fun pushUrlAnnotation(urlAnnotation: UrlAnnotation): Int
Attach the given UrlAnnotation to any appended text until a corresponding pop is called.
Parameters
| urlAnnotation | A UrlAnnotation object that stores the URL being linked to. |
pushLink
public fun pushLink(link: LinkAnnotation): Int
Attach the given LinkAnnotation to any appended text until a corresponding pop is called.
Parameters
| link | A LinkAnnotation object that stores the URL or clickable tag being linked to. |
pop
public fun pop()
Ends the style or annotation that was added via a push operation before.
pop
public fun pop(index: Int)
Ends the styles or annotation up to and including the pushStyle or pushStringAnnotation that returned the given index.
Parameters
| index | the result of the a previous pushStyle or pushStringAnnotation in order to pop to |
toAnnotatedString
public fun toAnnotatedString(): AnnotatedString
Constructs an AnnotatedString based on the configurations applied to the Builder.
Members
BulletScope
public class BulletScope internal constructor(internal val builder: Builder)
Scope for a bullet list
Annotation
public sealed interface Annotation
Defines annotations that specify additional information to apply to ranges of text within the given AnnotatedString.
The AnnotatedString supports annotations that provide different kind of information, such as
- SpanStyle specifies character level styling such as color, font, letter spacing etc.
- ParagraphStyle for configuring styling on a paragraph level such as line heights, text
- LinkAnnotation to mark links in the text.
- TtsAnnotation provides information to assistive technologies such as screen readers.
- Custom annotations using the StringAnnotation.
aligning, text direction etc.
Members
Companion
public companion object
Properties
Saver
public val Saver: Saver<Annotation, Any> = AnnotationSaver
Saves and restores AnnotatedString.Annotation objects.
Supports the following annotation types:
- ParagraphStyle
- SpanStyle
- VerbatimTtsAnnotation
- UrlAnnotation
- LinkAnnotation.Url
- LinkAnnotation.Clickable
- StringAnnotation
Note: Does not preserve LinkInteractionListener of LinkAnnotations, and Bullet annotations are not preserved at the moment. Handle saving and restoring them manually if required.
Companion
public companion object
Properties
Saver
public val Saver: Saver<AnnotatedString, *> = AnnotatedStringSaver
The default Saver implementation for AnnotatedString.
Note this Saver doesn't preserve the LinkInteractionListener of the links. You should handle this case manually if required (check https://issuetracker.google.com/issues/332901550 for an example).