TextView is an extremely powerful view in Android. Obviously, they’re able to display text, but they can also display several styles of text, different fonts or colors, and even inline images, all within a single TextView
. You can have specific portions of text respond to click events and really associate any object you want with any portion of text. These ranges of text are generically referred to as spans as in a span (range) of bold text or a span of subscript.
First, you should know about the two main types of spans defined by the interfaces CharacterStyle
and ParagraphStyle
. As you can probably guess, these interfaces refer to spans that affect one or more characters and spans that affect entire paragraphs, respectively. Most spans will implement one of these two interfaces (although many implement more than just these). See the following list of built-in spans to get an idea about what is already supported:
AbsoluteSizeSpan
. A span that allows you to specify an exact size in pixels or density independent pixels.AlignmentSpan
. A span that attaches an alignment (from Layout.Alignment).BackgroundColorSpan
. A span that specifies a background color (the color behind the text, such as for highlighting).ClickableSpan
. A span that has an onClick
method that is triggered. (This class is abstract, so you can extend it with a class that specifies the onClick behavior.)DrawableMarginSpan
. A span that draws a Drawable
plus the specified amount of spacing.DynamicDrawableSpan
. A span that you can extend to provide a Drawable
that may change (but the size must remain the same).EasyEditSpan
. A span that just marks some text so that the TextView
can easily delete it.ForegroundColorSpan
. A span that changes the color of the text (basically just called setColor(int)
on the TextPaint
object).IconMarginSpan
. A span that draws a Bitmap
plus the specified amount of spacing.ImageSpan
. A span that draws an image specified as a Bitmap
, Drawable
, URI
, or resource ID.LeadingMarginSpan
. A span that adjusts the margin.LocaleSpan
. A span that changes the locale of text (available in API level 17 and above).MaskFilterSpan
. A span that sets the MaskFilter
of the TextPaint
(such as for blurring or embossing).MetricAffectingSpan
. A span that affects the height and/or width of characters (this is an abstract class).QuoteSpan
. A span that puts a vertical line to the left of the selected text to indicate it is a quote; by default the line is blue.RasterizerSpan
. A span that sets the Rasterizer
of the TextPaint
(generally not useful to you).RelativeSizeSpan
. A span that changes the text size relative to the supplied float (for instance, setting a 0.5 float will cause the text to render at half size).ReplacementSpan
. A span that can be extended when something custom is drawn in place of the spanned text (e.g., ImageSpan
extends this).ScaleXSpan
. A span that provides a multiplier to use when calling the TextPaint
’s setTextScaleX(float)
method. (In other words, setting this to 0.5 will cause the text to be scaled to half size along the X-axis, thus appearing squished.)StrikethroughSpan
. A span that simply passes true to the TextPaint
’s setStrikeThruText(boolean)
method, causing the text to have a line through it (useful for showing deleted text, such as in a draft of a document).StyleSpan
. A span that adds bold and/or italic to the text.SubscriptSpan
. A span that makes the text subscript (below the baseline).SuggestionSpan
. A span that holds possible replacement suggestions, such as for a incorrectly spelled word (available in API level 14 and above).SuperscriptSpan
. A span that makes the text superscript (above the baseline).TabStopSpan
. A span that allows you to specify an offset from the leading margin of a line.TextAppearanceSpan
. A span that allows you to pass in a TextAppearance
for styling.TypefaceSpan
. A span that uses a specific typeface family (monospace, serif, or sans-serif only).UnderlineSpan
. A span that underlines the text.URLSpan
. A ClickableSpan
that attempts to view the specified URL when clicked.Add click to part of string
Following is layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:gravity="center"> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Give us a rating..." /> </LinearLayout>
Following is code
TextView tvTitle = (TextView) findViewById(R.id.tvTitle); String text = "Give us a rating..."; // initialize a new ClickableSpan ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View view) { Toast.makeText(activity, "us", Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); int color = ContextCompat.getColor(activity, R.color.colorPrimary); ds.setColor(color); ds.setUnderlineText(false); } }; // initialize a new SpannableStringBuilder instance SpannableStringBuilder ssBuilder = new SpannableStringBuilder(text); // apply the clickable text to the span ssBuilder.setSpan( clickableSpan, // span to add text.indexOf("us"), // start of the span (inclusive) text.indexOf("us") + String.valueOf("us").length(), // end of the span (exclusive) Spanned.SPAN_EXCLUSIVE_EXCLUSIVE // do not extend the span when text add later ); // underline ssBuilder.setSpan( new UnderlineSpan(), text.indexOf("Give"), text.indexOf("Give") + String.valueOf("Give").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); // bold ssBuilder.setSpan( new StyleSpan(Typeface.BOLD), text.indexOf("Give"), text.indexOf("Give") + String.valueOf("Give").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); tvTitle.setText(ssBuilder); // this step is mandated for the url and clickable styles tvTitle.setMovementMethod(LinkMovementMethod.getInstance()); tvTitle.setHighlightColor(Color.TRANSPARENT);
The URLSpan
and ClickableSpan
both require the movementMethod
of the TextView
to be set as LinkMovementMethod
.
Change color of word in string
Following is code
String text = "Give us a rating..."; SpannableStringBuilder ssBuilder = new SpannableStringBuilder(text); ssBuilder.setSpan( new ForegroundColorSpan(Color.RED), text.indexOf("Give"), text.indexOf("Give") + String.valueOf("Give").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); ssBuilder.setSpan( new ForegroundColorSpan(Color.BLUE), text.indexOf("us"), text.indexOf("us") + String.valueOf("us").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); ssBuilder.setSpan( new ForegroundColorSpan(Color.GREEN), text.indexOf("rating"), text.indexOf("rating") + String.valueOf("rating").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); tvTitle.setText(ssBuilder);
Following code shows random colors for letters
Spannable span = new SpannableString(text); for (int i = 0, len = colorfulText.length(); i < len; i++ ) { span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } tvTitle.setText(span); private int getRandomColor(){ Random rnd = new Random(); return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); }
Other spans
Change relative size of specified string
int flag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE; ssBuilder.setSpan(new RelativeSizeSpan(2), 0, text1.length(), flag); ssBuilder.setSpan(new RelativeSizeSpan(0.5f), 0, text2.length(), flag);
Change background color of specified string
ssBuilder.setSpan(new BackgroundColorSpan(Color.CYAN), 0, text3.length(), flag);
Set subscript and superscript for string
ssBuilder.setSpan(new SubscriptSpan(), 0, text4.length(), flag); ssBuilder.setSpan(new SuperscriptSpan(), 0, text5.length(), flag);
Set url for string
styledString.setSpan(new URLSpan("http://www.google.com"), 0, text6.length(), flag);
ImageSpan
allows you to use images for span.
SpannableString ssBuilder = new SpannableString("This text is strange"); ssBuilder.setSpan(new ImageSpan(this, R.drawable.ic_launcher), 5, 9, flag);
TextAppearanceSpan
allows you to set a resource appearance on a character.
SpannableString ssBuilder = new SpannableString("This text is strange"); ssBuilder.setSpan(new TextAppearanceSpan(this, R.style.SpanTextAppearance), 5, 9, flag);
Style is following
<style name="SpanTextAppearance" parent="@android:style/TextAppearance"> <item name="android:textColor">#FF0000</item> <item name="android:textSize">20sp</item> <item name="android:textStyle">italic</item> </style>
You could also use the Html.fromHtml method to create Spanned Strings using html tags. For an unofficial list of supported tags see this.
Another way to decorate TextView is TextDecorator.
Span for Toast
Spannable text = new SpannableString("Italic green text in toast"); text.setSpan(new StyleSpan(Typeface.ITALIC), 0, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(new ForegroundColorSpan(Color.GREEN), 0, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Toast.makeText(activity, text, Toast.LENGTH_LONG).show();
Bonus
Sometimes it is useful to leave a blank at the end of a resource string representing an on-screen field name. To do it insert \u0020
directly in the XML for a blank you would like to preserve.
Example
<string name="score_text">Score :\u0020</string>
Useful links