Even a developer-friendly mobile platform like
Android can have a developer
feeling a little lost when trying to perform simple tasks when you're
unfamiliar with the platform.
One of these simple, however poorly documented, tasks is rich-style text formatting within a TextView.
SpannableString
While it's possible to set a TextView's text property to a simple String and configure the TextView to have the formatting you desire you're then limited in how granular you can control the formatting within the TextView itself. The SpannableString class allows you to easily format certain pieces (spans) of a string one way and other pieces another by applying extensions of CharacterStyle (i.e. ForegroundColorSpan) via the setSpan method.
In the end this isn't limited to formatting. It also allows the developer to add behaviors to spans such as reacting to click events.
Example
Here's an example onCreate method of an Activity. This assumes there's a main.xml layout with a TextView identified by "rich_text".
Essentially this code will set a TextView's text to the familiar, "Lorem ipsum dolor sit amet" and perform the following formatting:
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
richTextView = (TextView)findViewById(R.id.rich_text);
// this is the text we'll be operating on
SpannableString text = new SpannableString("Lorem ipsum dolor sit amet");
// make "Lorem" (characters 0 to 5) red
text.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);
// make "ipsum" (characters 6 to 11) one and a half time bigger than the textbox
text.setSpan(new RelativeSizeSpan(1.5f), 6, 11, 0);
// make "dolor" (characters 12 to 17) display a toast message when touched
final Context context = this;
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View view) {
Toast.makeText(context, "dolor", Toast.LENGTH_LONG).show();
}
};
text.setSpan(clickableSpan, 12, 17, 0);
// make "sit" (characters 18 to 21) struck through
text.setSpan(new StrikethroughSpan(), 18, 21, 0);
// make "amet" (characters 22 to 26) twice as big, green and a link to this site.
// it's important to set the color after the URLSpan or the standard
// link color will override it.
text.setSpan(new RelativeSizeSpan(2f), 22, 26, 0);
text.setSpan(new URLSpan("http://www.chrisumbel.com"), 22, 26, 0);
text.setSpan(new ForegroundColorSpan(Color.GREEN), 22, 26, 0);
// make our ClickableSpans and URLSpans work
richTextView.setMovementMethod(LinkMovementMethod.getInstance());
// shove our styled text into the TextView
richTextView.setText(text, BufferType.SPANNABLE);
}
The results of which will look something like:

Note that we set the TextView's movement method to a LinkMovementMethod instance. Without that the ClickableSpan and URLSpans won't perform their intended actions.
Next Steps
This covers the fundamental concepts, but there are many extensions of CharacterStyle I haven't covered here. Check out the CharacterStyle documentation for more details.
Also note that a SpannableStringBuilder is provided for building large spannables from smaller pieces.
Sat Aug 28 2010 18:25:02 GMT+0000 (UTC)
Comment Feed -
Permalink
Thanks a lot for this article , need this for my project And for concatenation we can use TextUtils.concat() which keep the spansby Arialia on Fri Apr 15 2011 08:39:12 GMT+0000 (UTC)
Very interesting article. I thank you so much to have proposed this pratical example that enables to understand this notion which is not well developped in the Android's documentation. Hope you're keep on doing such good stuff ! ;o)by Android's beginner on Wed Nov 09 2011 20:35:13 GMT+0000 (UTC)
Thanks a lot for this article , need this for my project And for concatenation we can use TextUtilsby chloe bags on Sat Nov 26 2011 07:15:42 GMT+0000 (UTC)
Thanks a bunch, great example and exactly what I was after.by Jason on Thu Feb 16 2012 10:54:45 GMT+0000 (UTC)
Thanks a lot! Finally a clear answer and how to!!by Noel on Mon Mar 26 2012 21:10:43 GMT+0000 (UTC)
The font family you use on your website is not pleasing to the eye.by Ben on Tue Sep 11 2012 11:34:55 GMT+0000 (UTC)