Friday, 14 March 2014

Android SpannableString Example

The SpannableString in android is an excellent way to style strings in a TextView.
Put simply, it allows a TextView to provide different styles to different areas of text.

In the following example, we create in Activity to display a single TextView.

The TextView will use a SpannableString as its content, which will illustrate some of the available styles.

Here' what we're gonna do with the text :
  • Make it larger
  • Bold
  • Underline
  • Italicize
  • Strike-through
  • Colored
  • Highlighted
  • Show as superscript
  • Show as subscript
  • Show as a link
  • Make it clickable. 

The finished Activity will look like this :




So lets's dig in :). For simplicity, I'v limited myself to the onCreate() method of the Activity.
@Override
    protected void onCreate(Bundle savedInstanceState) {
        
     super.onCreate(savedInstanceState);
        
     SpannableString styledString
      = new SpannableString("Large\n\n"     // index 0 - 5
           + "Bold\n\n"          // index 7 - 11
           + "Underlined\n\n"    // index 13 - 23
           + "Italic\n\n"        // index 25 - 31
           + "Strikethrough\n\n" // index 33 - 46
           + "Colored\n\n"       // index 48 - 55
           + "Highlighted\n\n"   // index 57 - 68
           + "K Superscript\n\n" // "Superscript" index 72 - 83 
           + "K Subscript\n\n"   // "Subscript" index 87 - 96
           + "Url\n\n"           //  index 98 - 101
           + "Clickable\n\n");   // index 103 - 112
     
     // make the text twice as large
     styledString.setSpan(new RelativeSizeSpan(2f), 0, 5, 0);
     
     // make text bold
     styledString.setSpan(new StyleSpan(Typeface.BOLD), 7, 11, 0);
     
     // underline text
     styledString.setSpan(new UnderlineSpan(), 13, 23, 0);
     
     // make text italic
     styledString.setSpan(new StyleSpan(Typeface.ITALIC), 25, 31, 0);
     
     styledString.setSpan(new StrikethroughSpan(), 33, 46, 0);
     
     // change text color
     styledString.setSpan(new ForegroundColorSpan(Color.GREEN), 48, 55, 0);
     
     // highlight text
     styledString.setSpan(new BackgroundColorSpan(Color.CYAN), 57, 68, 0);
     
     // superscript
     styledString.setSpan(new SuperscriptSpan(), 72, 83, 0);
     // make the superscript text smaller
     styledString.setSpan(new RelativeSizeSpan(0.5f), 72, 83, 0);
     
     // subscript
     styledString.setSpan(new SubscriptSpan(), 87, 96, 0);
     // make the subscript text smaller
     styledString.setSpan(new RelativeSizeSpan(0.5f), 87, 96, 0);
     
     // url
     styledString.setSpan(new URLSpan("http://www.google.com"), 98, 101, 0);
     
     // clickable text
     ClickableSpan clickableSpan = new ClickableSpan() {
   
   @Override
   public void onClick(View widget) {
    // We display a Toast. You could do anything you want here.
    Toast.makeText(SpanExample.this, "Clicked", Toast.LENGTH_SHORT).show();
    
   }
  };
  
  styledString.setSpan(clickableSpan, 103, 112, 0);
  
  
  // Give the styled string to a TextView
  TextView textView = new TextView(this);
  
  // this step is mandated for the url and clickable styles.
  textView.setMovementMethod(LinkMovementMethod.getInstance());
  
  // make it neat
  textView.setGravity(Gravity.CENTER);
  textView.setBackgroundColor(Color.WHITE);
  
  textView.setText(styledString);
  
  setContentView(textView);

    }

A little explanation

The comments explain most of the stuff but here's a bit more.
The parameters for the setSpan() method are 
  • what : The type of Span.
  • start : The inclusive start index for the Span.
  • end : The exclusive end index for the Span.
  • flag : Additional configuration. Refer to the constants here

Notes :

  • Multiple spans can be applied to the same area in a String. This has been shown above in the superscript span, where the text was both reduced in size and made superscript.
  • The URLSpan and ClickableSpan both require the movementMethod of the TextView to be set as LinkMovementMethod.
  • SpannableStrings are immutable. If this is a concern, use a SpannableStringBuilder.
  • If you're using a string resource as the content of the TextView, some of the above styles can be declared in the resource itself. See this to check how.
  • You could also use the Html.fromHtml method to create Spanned Strings using html tags. For an unofficial list of supported tags see this.
For any questions or suggestions, please leave comments.Adios :).


21 comments:

  1. nicely explained..useful tutorial..

    ReplyDelete
  2. That's a great example.
    Thanks!

    ReplyDelete
  3. Very useful and clear. Thank you for this!

    ReplyDelete
  4. Finally something that's simple and clear :)

    ReplyDelete
  5. Great! Thanks Very Much!

    ReplyDelete
  6. excellent tutorial, saved my life and time :P

    ReplyDelete
  7. Very well explained. Keep it up! :)

    ReplyDelete
  8. Great explaination. easy to understand , thank you

    ReplyDelete