3. Spannables
What are they?
Why would I need to use
them?
Why not just HTML?
Types
Editable
SpannableString / Builder
SpannableFactory
Priority
Spanned
Speciality
Language with
LocaleSpan
Making Pictures
DrawableSpan
ImageSpan
IconMarginSpan
DynamicSpans
MaskFilterSpan
BackgroundColorSpan
Accessibility
TtsSpan
TTsSpanBuilder
String / General Spans
TextAppearanceSpan
TypefaceSpan
BulletSpan
StrikethroughSpan
QuoteSpan….. etc.
StyleSpan
ReplacementSpan
ClickableSpan
RelativeSizeSpan
SubscriptSpan
SuggestionSpan
SuperscriptSpan
Spanning the Details
6. You can have multiple types of objects in a SINGLE LINE✓
✓
✓
✓
✓
Renders Quickly, more so than large Html.toText() content (OMG less data!)
Allows more programmatic control and simpler XML layouts
Perfect Scaling on every device - future proof *depending on use*
Use embedded resources like Fonts and Pictures
But Why?
7. Simplifying Views
You can have a single View
replace appx 4-6 Views /
Objects in even simple
examples.
Only Way
Sometimes there just isn’t a
good way to do it without
making your own custom view
object.
Use existing Android
Resources easily.
Better Views
8. Spannable
Base class
Supports All Span Types
Allows you to have a Span
without content in its
Constructor
Ideal for when an object will
be reassigned and reused
SpannableFactory
SpannableString
SpannableString.Builder
Immutable
Basically, it is Spannable +
String with or without options
in it’s Constructor
Supports everything that a
standard Spannable does
Editable
Dynamic
Edit-able <
Use for EditText input
Ideally, good for custom
chatbots
Supports all Span Types (but
be careful on some as the
span may not be edit-able)
Spannables Types
9. The EZ-E of Strings
Input: Simple String Example
Output: Simple String Example
String simpleString = "Simple String Example";
String textToBold = "Simple";
SpannableString content =new SpannableString(simpleString);
//Bold Italic Text
content.setSpan(new StyleSpan(Typeface.BOLD_ITALIC),
simpleString.indexOf(textToBold),
simpleString.indexOf(textToBold) + textToBold.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //Spanned
myTextView.setText(content);
Simple Text Spannables & Spans
10. The Only-Way Strings
Input: Simple String Example
Continued New Output:
Simple String Example
String textToStrike = "String";
//Strikethrough - not possible using Html.toText()
content.setSpan(new StrikethroughSpan(),
simpleString.indexOf(textToStrike),
simpleString.indexOf(textToBold) + textToBold.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //Spanned
//Change Font Color (since font is the foreground)
content.setSpan(new
ForegroundColorSpan(getColor(Color.PURPLE)),
simpleString.indexOf(textToStrike),
simpleString.indexOf(textToBold) + textToBold.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //Spanned
Fancy Text Spans
11. The Only-Way Strings
Input: Simple String Example
Continued New Output:
Simple String Example
String textToClick= "Example";
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//Set Some Kind of Clickable Action
startActivity(new Intent(MyActivity.this, NextActivity.class));}
@Override
public void updateDrawState(TextPaint textPaint) {
super.updateDrawState(textPaint);
textPaint.setUnderlineText(true);
textPaint.setColor(getColor(Color.BLUE);}
};
Clicky Action Spans
12. Woah Canvas
ReplacementSpan has both
Canvas and Characters which is
good for Combining Objects on
top of each other without
Overdraw
public class RedRoundedBackgroundSpan extends ReplacementSpan {
private int CORNER_RADIUS = 5;
private int backgroundColor = 0;
private int textColor = 0;
public RedRoundedBackgroundSpan(Context context) {super();
backgroundColor = context.getColor(Color.RED;
textColor = context.getColor(Color.WHITE);}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
Paint paint) {
RectF rect = new RectF(x, top, x + measureText(paint, text, start, end), bottom);
paint.setColor(backgroundColor);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint);
paint.setColor(textColor);
canvas.drawText(text, start, end, x, y, paint);}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return Math.round(paint.measureText(text, start, end)); }
private float measureText(Paint paint, CharSequence text, int start, int end) {
return paint.measureText(text, start, end);} } //End of class
Custom Replacement Spans
Canvas skillz always useful
13. Usual Way, not very malleable and can’t do fancy Locale / Language :
SpannableString content =
new SpannableString(String.format(Locale.US, "%.2f",
"Forced Locale String"));
Using LocaleSpan:
LocaleSpan localSpan = new LocaleSpan(new Locale("en", "US"));
Speciality Spans
Locale Pictures Accessibility
14. Adding in a Bitmap or Drawable
Dynamic / DrawableSpan, ImageSpan, IconMarginSpan
Drawable yao = getResources().getDrawable(R.drawable.reallyface);
yao.setBounds(0, 0, yao.getIntrinsicWidth(), yao.getIntrinsicHeight());
ImageSpan span = new ImageSpan(yao, ImageSpan.ALIGN_BASELINE);
YES!
Speciality Spans
Locale Pictures Accessibility
15. Playing with Color
BackgroundSpan / ForegroundSpan / MaskFilterSpan or like here with Replacement Span
Speciality Spans
Locale Pictures Accessibility
BlurMaskFilter blurFilter = new BlurMaskFilter(2.0f,
BlurMaskFilter.Blur.NORMAL);
MaskFilterSpan blurMask = new MaskFilterSpan(blurFilter);
//Now, you can make text Blurry! Any type of Mask can be used here.
16. Accessibility with Text-to-Speech
TTSSpan and all of its children are part of the Text-To-Speech parsing of your text boxes.
public static TtsSpan getPhoneTtsSpan(String phoneNumberString){
final TtsSpan.TelephoneBuilder builder=new TtsSpan.TelephoneBuilder();
if (phoneNumber == null) {
builder.setNumberParts(splitAtNonNumerics(phoneNumberString)); }
else {
if (phoneNumber.hasCountryCode()) {
builder.setCountryCode(Integer.toString(phoneNumber.getCountryCode()))}
builder.setNumberParts(Long.toString(phoneNumber.getNationalNumber()));
}
return builder.build();
}
Speciality Spans
Locale Pictures Accessibility
17. SpanWatcher - Essentially a listener for span removal /add / change✓
✓
✓
✓
✓
Animating Spans using SpanWatcher (usually in an Editable)
The MANY types of Spanned (Inclusive, Exclusive, etc)
Playing with making many types of Canvas backgrounds
GO BACK and REMOVE ALL Html.toText() references in ALL APPS!
Bonus Points