Note that this cheat sheet will explain everything using text.setSpan
. The code that around this should resemble something like this.
val text = SpannableString("Hello World") text.setSpan(...) textview.setText(text, TextView.BufferType.SPANNABLE)
Bold
text.setSpan( StyleSpan(android.graphics.Typeface.BOLD), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Italic
text.setSpan( StyleSpan(android.graphics.Typeface.ITALIC), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Bold Italic
text.setSpan( StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Hyperlink
text.setSpan( URLSpan(url), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Text Colour (Forground Colour)
text.setSpan( ForegroundColorSpan(Color.BLUE), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Background Colour
text.setSpan( BackgroundColorSpan(Color.BLUE), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Superscript
text.setSpan( SuperscriptSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Subscript
text.setSpan( SubscriptSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Bulleted List
text.setSpan( BulletSpan(gapWidth, bulletColour), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
BulletSpan extends LeadingMarginSpan so the first character of the span must be at the start of a paragraph and the span will cover the whole of each start of paragraphs within its range.
Ordered List
var itemOrdinal = 1 var currentItemIndex = position while (textBodies[currentItemIndex].type == TextBodyType.ORDERED_LIST_ITEM && currentItemIndex > 0) { currentItemIndex -= 1 if (textBodies[currentItemIndex].type == TextBodyType.ORDERED_LIST_ITEM) itemOrdinal += 1 } spannedText = SpannableString("$itemOrdinal. $spannedText")
Not exactly a span but there’s no span for numbered lists so you’ll have to get hacky. This is one such example.
Quote
text.setSpan( QuoteSpan(), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
QuoteSpan extends LeadingMarginSpan so the first character of the span must be at the start of a paragraph and the span will cover the whole of each start of paragraphs within its range.
Drawable
text.setSpan( DrawableMarginSpan(drawable, padding), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
DrawableMarginSpan extends LeadingMarginSpan so the first character of the span must be at the start of a paragraph and the span will cover the whole of each start of paragraphs within its range.
Typeface / Font Family
text.setSpan( TypefaceSpan(typeface), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
TypefaceSpan needs at least API level 28 (Android P).
Scale X
text.setSpan( ScaleXSpan(scale), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Relative Size
text.setSpan( RelativeSizeSpan(scale), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Absolute Size
text.setSpan( AbsoluteSizeSpan(absoluteSize), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Text Appearance / Style
text.setSpan( TextAppearanceSpan(context, appearanceRes), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Mask Filter
text.setSpan( MaskFilterSpan(BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL)), 0, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
Strikethrough
text.setSpan( StrikethroughSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
Underline
text.setSpan( UnderlineSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
Spanned vs SpannableString vs SpannableStringBuilder
These differ by whether their spans or text are mutable or not.
Spanned – Immutable span and text.
SpannableString – Mutable span, immutable text
SpannableStringBuilder – Mutable span and text
Spannable Flags
When you set a span, you must specify a flag to determine how the span behaves in terms of how it affects text that comes before and after it, as well as text that gets added later on. Some basic ones include:
SPAN_EXCLUSIVE_EXCLUSIVE
SPAN_EXCLUSIVE_INCLUSIVE
SPAN_INCLUSIVE_EXCLUSIVE
SPAN_INCLUSIVE_INCLUSIVE
Conclusion
Let me know down in the comments if you found this useful, if I missed anything, or if there are any other cheat sheets you’d like me to do in the future. As always, happy coding ༼ つ ◕_◕ ༽つ