The magic of SpannableString by Samuel Dionne

The magic of SpannableString by Samuel Dionne

SpannableString is a powerful concept that goes beyond clickable links in a TextView. We’ll look at different standard use cases and other more daring. We’ll check the different already available Span types and look at how we can create our very own.

https://gdgmontreal.com/2019/11/15/november-meetup/
https://youtu.be/U3cBsubemPc

1b77dd441f657f5aefb3e21283b252e6?s=128

GDG Montreal

November 27, 2019
Tweet

Transcript

  1. Spannable Magic What are spans and what can we do

    with them
  2. Outline What is are Span and Spannable strings What can

    we do with them How do they work How to create a custom span Questions
  3. What are Spans and Spannable strings

  4. Differents ways to style text Changing all the text at

    once Here is my example text <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ff0000" android:textSize="22sp" android:textStyle="bold" />
  5. Differents ways to style text Changing only part of the

    text Here is my example text <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:magic="???" />
  6. Here come the Span Spans are a way to apply

    style to different part of a strings
  7. Here come the Span Spans are a way to apply

    style to different part of a strings Here is my example text
  8. Here come the Span Spans are a way to apply

    style to different part of a strings Here is my example text SpannableString str = new SpannableString(“Here is my example”); str.setSpan(new UnderlineSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); str.setSpan(new ForegroundColorSpan(0xffff0000), 8, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); str.setSpan(new StyleSpan(BOLC), 19, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  9. Here come the Span str.setSpan(new UnderlineSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Span:

    what style we want Span Start index End index Flags
  10. Here come the Span str.setSpan(new UnderlineSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Span:

    what style we want Start index: where to start from Span Start index End index Flags
  11. Here come the Span str.setSpan(new UnderlineSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Span:

    what style we want Start index: where to start from End index: where to end Span Start index End index Flags
  12. Here come the Span str.setSpan(new UnderlineSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Span:

    what style we want Start index: where to start from End index: where to end Flags: what should happen when the text change Span Start index End index Flags
  13. Text change behaviours Here is my text Spannable.SPAN_EXCLUSIVE_EXCLUSIVE Spannable.SPAN_INCLUSIVE_EXCLUSIVE Spannable.SPAN_EXCLUSIVE_INCLUSIVE

    Spannable.SPAN_INCLUSIVE_INCLUSIVE Here is my super-text-er Here is my super-text-er Here is my super-text-er Here is my super-text-er Here is my super-text-er
  14. How to apply span? It depends of what part can

    change
  15. How to apply span? It depends of what part can

    change SpannedString Text is immutable Spans are immutables
  16. How to apply span? It depends of what part can

    change SpannedString Text is immutable Spans are immutables SpannableString Text is immutable Spans are mutables
  17. How to apply span? It depends of what part can

    change SpannedString Text is immutable Spans are immutables SpannableString Text is immutable Spans are mutables SpannableStringBuilder Text is mutable Spans are mutables
  18. What can we do with them

  19. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  20. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  21. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  22. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan • BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan

    DynamicDrawableSpan EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  23. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  24. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  25. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan S ubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  26. Provided spans AbsoluteSizeSpan AlignmentSpan.Standard BackgroundColorSpan BulletSpan CharacterStyle ClickableSpan DrawableMarginSpan DynamicDrawableSpan

    EasyEditSpan ForegroundColorSpan IconMarginSpan ImageSpan LeadingMarginSpan.Standard MaskFilterSpan MetricAffectingSpan QuoteSpan RelativeSizeSpan ReplacementSpan ScaleXSpan StrikethroughSpan StyleSpan SubscriptSpan SuggestionSpan SuperscriptSpan TabStopSpan.Standard TextAppearanceSpan
  27. How do they work

  28. 3 types of Spans

  29. 3 types of Spans Character Affecting Spans Appearance Affecting Spans

    Only affect the style No effect on the layout Example: ForegroundColorSpan
  30. 3 types of Spans Character Affecting Spans Appearance Affecting Spans

    Only affect the style No effect on the layout Metric Affecting Spans Affect the dimensions of the text Example: AbsoluteSizeSpan
  31. 3 types of Spans Character Affecting Spans Appearance Affecting Spans

    Only affect the style No effect on the layout Metric Affecting Spans Affect the dimensions of the text Paragraph Affecting Spans A paragraph is delimited by \n Example: QuoteSpan
  32. How to create a custom span

  33. Mise en scène 01 Julia UI Designer

  34. 1 Mise en scène 02 2 min 10 min 1

    h 25 min
  35. 1 Mise en scène 03 2 min

  36. 1 Mise en scène 03 2 min AbsoluteSizeSpan

  37. 1 Mise en scène 03 2 min AbsoluteSizeSpan StyleSpan

  38. 1 Mise en scène 03 2 min AbsoluteSizeSpan StyleSpan ImageSpan

  39. 1 Mise en scène 04 2 min AbsoluteSizeSpan StyleSpan ImageSpan

  40. 1 Mise en scène 04 2 min AbsoluteSizeSpan StyleSpan ImageSpan

  41. 1 Solution 2 min AbsoluteSizeSpan StyleSpan SuperscriptImageSpan

  42. SuperscriptImageSpan.java public int getSize(Paint paint, CharSequence text, int start, int

    end, Paint.FontMetricsInt fm); public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint);
  43. SuperscriptImageSpan.java public int getSize(Paint paint, CharSequence text, int start, int

    end, Paint.FontMetricsInt fm); public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint);
  44. SuperscriptImageSpan.java public int getSize(Paint paint, CharSequence text, int start, int

    end, Paint.FontMetricsInt fm); public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint);
  45. Paint.FontMetricsInt

  46. SuperscriptImageSpan.java public int getSize(Paint paint, CharSequence text, int start, int

    end, Paint.FontMetricsInt fm) { Rect rect = drawable.getBounds(); if (fm != null) { fm.top = fm.ascent - rect.bottom / 2; } return rect.right; }
  47. SuperscriptImageSpan.java public void draw(Canvas canvas, CharSequence text, int start, int

    end, float x, int top, int y, int bottom, Paint paint) { canvas.save(); canvas.translate(x, drawable.getBounds().bottom / 2); drawable.draw(canvas); canvas.restore(); }
  48. 1 Finally 2 min AbsoluteSizeSpan StyleSpan SuperscriptImageSpan

  49. Questions

  50. Thank you!

  51. References Spantastic text styling with Spans String Manipulation Using SpannableString

    Android Developer Doc