In this video Google gave an example for formatting portions of a String
based on Annotation
tags that can be used to set a key/value pairs in a String
within strings.xml
.
Here is an example for this:
strings.xml
<string name="test">Hello <annotation font="sans-serif-medium">World!</annotation></string>
Kotlin Code:
val spannedString = getText(R.string.title) as SpannedString
val annotations = spannedString.getSpans(0, spannedString.length, Annotation::class.java)
for (annotation in annotations) {
if (annotation.key == "font") {
val fontName = annotation.value
val typeFace: Typeface = ...
spannable.setSpan(TypefaceSpan(typeFace), abstract.getSpanStart(annotation),
abstract.getSpanEnd(annotation), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
This also has been used with ReplacementSpan
in this article to tackle the problem of the ReplacementSpans
that they can not flow into the next line of text.
My Question is:
I need to create/remove Annotation tags dynamically so that I can programmatically remove tags from portions of text that are marked with annotation tags or add tags to non-annotated text.
How can I achieve that?
Normally we attach String
spans with an implementation of ParcelableSpan
like ForegroundColorSpan
, BackgroundColorSpan
, UnderlineSpan
, TypefaceSpan
.. etc
And by observing that the Annotation
also implements ParcelableSpan
as well, we can use setSpan()
to attach annotation to it, and add the key/value pairs to its constructor.
My other observation is that setSpan()
actually accepts an Object
as a first argument.
So referring to the referenced question article example (GitHub Repo); to set annotation programmatically:
val span = SpannableString("value \n 1 Some Value Value 2")
span.setSpan(Annotation("", "rounded"), 0, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
span.setSpan(Annotation("", "rounded"), 15, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = span
The key of the Annotation
doesn't matter in this example, as we only need its tag/value. So kept it as an empty String.
The result: