Background
In the process of application development, it is often seen that some information with different font styles is like the time and charging information on the default lockscreen. In a similar situation, the first possible response is to use different textviews. Different font styles are set for each textview to meet the requirements.
Android is recommended. text. *; and Android. text. style. *; the following component implements richtext: that is, set different font styles in the same textview. For some applications, such as text editing, notepad, MMS, and SMS, you must use these components to achieve the desired display effect.
The main basic tool classes are Android. Text. spanned; Android. Text. spannablestring; Android. Text. spannablestringbuilder; these classes are used to replace regular strings. Spannablestring and spannablestringbuilder can be used to set different spans. These spans are used to implement rich text, such as bold, italic, foreground color, background color, font size, and font style. Android. text. style. * defines many span types for use.
This is the related API class general hierarchy:
Because spannable and so on finally implement the charsequence interface, you can directly set spannablestring and spannablestringbuilder to textview through textview. settext.
Usage
When you want to display rich text information, you can create a spannablestring or spannablestringbuilder. The difference is that spannablestring is like a string, and a string is input when constructing an object, after that, you cannot change the string content or splice multiple spannablestrings. The spannablestringbuilder is more like a stringbuilder. It can splice multiple strings through its append () method:
SpannableString word = new SpannableString("The quick fox jumps over the lazy dog");SpannableStringBuilder multiWord = new SpannableStringBuilder();multiWord.append("The Quick Fox");multiWord.append("jumps over");multiWord.append("the lazy dog");
After the spannable object is created, you can set the span for them to implement the expected Rich Text. Common spans include:
- Absolutesizespan (INT size) ---- set the font size. The parameter is an absolute value, which is equivalent to the font size in word.
- Relativesizespan (float proportion) ---- set the font size. The parameter is a multiple of the default font size. For example, if the default font size is X, the configured font size is x * proportion, this is more flexible to use. proportion> 1 is zoom in, and proportion <1 is zoom out)
- Scalexspan (float proportion) ---- scale the font. Similar to the preceding one, the default value is 1. After setting it, It is multiplied by proportion. If it is greater than 1, it is Zoon in ), zoom out)
- Backgroundcolorspan (INT color) ---- background coloring. The parameter is a color value. You can directly use the constant defined in Android. Graphics. color, or use color. RGB (INT, Int, INT)
- Foregroundcolorspan (INT color) ---- foreground color, that is, the color of the word. The parameter is consistent with that of the background color.
- Typefacespan (string family) ---- font. The parameter is the font name, such as "sans" and "Sans-serif ".
- Stylespan (typeface style) ----- font style, such as bold and italic. The parameters are constants defined in Android. Graphics. typeface, such as typeface. Bold and typeface. italic.
- Strikethroughspan ---- if this style is set, there will be a line passing through all words from the middle, just like being crossed out.
When using these sytle spans, you can only pass the preceding constructor parameters. You do not need to set other attributes. If you need them, you can also set other attributes for them, for more information, see the documentation.
Both spannablestring and spannablestringbuilder have a method to set the preceding span:
/** * Set the style span to Spannable, such as SpannableString or SpannableStringBuilder * @param what --- the style span, such as StyleSpan * @param start --- the starting index of characters to which the style span to apply * @param end --- the ending index of characters to which the style span to apply * @param flags --- the flag specified to control */setSpan(Object what, int start, int end, int flags);
Among them, what is the style span to be set, start and end are the start position of span in string, and flags are used to control behavior, it is usually set to 0 or a constant defined in spanned. Commonly Used constants include:
- Spanned. span_exclusive_exclusive --- does not contain the endpoints of start and end at both ends
- Spanned. span_exclusive_inclusive
--- It does not contain end start, but contains the end point of end.
- Spanned. span_inclusive_exclusive
--- Contains the start at both ends, but does not include the endpoint of the end.
- Spanned. span_inclusive_inclusive --- contains the endpoints of start and end at both ends
It is like defining a range in mathematics, and opening or closing a range is the same. There are many other flags. For more information, see here. Here, we will focus on parameter 0. In many cases, if the preceding parameter is set, span will be applied from start to end of text, rather than between start and end, flag is required at this time.
0.
Linkify
In addition, you can also set its linkify attribute through textview. setautolink (INT), where textview automatically checks its content and identifies the phone
Number, web address or email address, which is identified as a hyperlink. You can click it to jump to the corresponding application, such as dialer, browser, or email. Linkify has several common options. For more information, see:
- Linkify. email_address -- only identifies the email address in the textview as a hyperlink. After clicking it, it will jump to the email and send an email to this address.
- Linkify. phone_numbers -- only identifies the phone number in textview as a hyperlink. After clicking it, it will jump to Dialer and call this number.
- Linkify. web_urls --
Only the URL in textview is identified as a hyperlink. After you click it, the URL is displayed in browser.
- Linkify. All -- this option identifies the special Uris supported by all systems, and then performs the corresponding operations.
Weight Selection
I personally think that the most common problem in software development is not how to use a certain technique, but when to use it, because there may be n different ways to achieve the same goal, we need to weigh the pros and cons and select the most appropriate one. As the saying goes, there is no best, but the most suitable cloud. As discussed earlier, you can use multiple textviews in addition to style span to display different information in different fonts. We need to summarize when to use stylespan and when to use multiple textviews:
- If multiple different categories of information are displayed, multiple textviews should be used to conveniently control and change their respective information. The example is the date and charging information on lockscreen by default, because they carry different information, multiple textviews should be used to present them separately.
- If the display is the same class information or the same information, stylespan should be used. For example, in a short message, you need to highlight the relevant information of the contact, or want some information such as highlight.
- If you want to implement Rich Text, you can only use style span.
- If you want to implement some special effects, you can also consider using stylespan. Setting different font styles is only an elementary application of style span. If you study it in depth, you can find many amazing effects.
Instance
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/text_view_font_1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_view_font_2" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_view_font_3" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_view_font_4" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_view_font_5" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </ScrollView></LinearLayout>
Source code:
package com.android.effective;import java.util.regex.Matcher;import java.util.regex.Pattern;import android.app.Activity;import android.graphics.Color;import android.graphics.Typeface;import android.os.Bundle;import android.text.Spannable;import android.text.SpannableString;import android.text.SpannableStringBuilder;import android.text.style.AbsoluteSizeSpan;import android.text.style.BackgroundColorSpan;import android.text.style.ForegroundColorSpan;import android.text.style.QuoteSpan;import android.text.style.RelativeSizeSpan;import android.text.style.ScaleXSpan;import android.text.style.StrikethroughSpan;import android.text.style.StyleSpan;import android.text.style.TypefaceSpan;import android.text.style.URLSpan;import android.text.util.Linkify;import android.widget.TextView;public class TextViewFontActivity extends Activity { @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.textview_font_1); // Demonstration of basic SpannableString and spans usage final TextView textWithString = (TextView) findViewById(R.id.text_view_font_1); String w = "The quick fox jumps over the lazy dog"; int start = w.indexOf('q'); int end = w.indexOf('k') + 1; Spannable word = new SpannableString(w); word.setSpan(new AbsoluteSizeSpan(22), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); word.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); word.setSpan(new BackgroundColorSpan(Color.RED), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); textWithString.setText(word); // Demonstration of basic SpannableStringBuilder and spans usage final TextView textWithBuilder = (TextView) findViewById(R.id.text_view_font_2); SpannableStringBuilder word2 = new SpannableStringBuilder(); final String one = "Freedom is nothing but a chance to be better!"; final String two = "The quick fox jumps over the lazy dog!"; final String three = "The tree of liberty must be refreshed from time to time with " + "the blood of patroits and tyrants!"; word2.append(one); start = 0; end = one.length(); word2.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); word2.append(two); start = end; end += two.length(); word2.setSpan(new ForegroundColorSpan(Color.CYAN), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); word2.append(three); start = end; end += three.length(); word2.setSpan(new URLSpan(three), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); textWithBuilder.setText(word2); // Troubleshooting when using SpannableStringBuilder final TextView textTroubles = (TextView) findViewById(R.id.text_view_font_3); SpannableStringBuilder word3 = new SpannableStringBuilder(); start = 0; end = one.length(); // Caution: must first append or set text to SpannableStringBuilder or SpannableString // then set the spans to them, otherwise, IndexOutOfBoundException is thrown when setting spans word3.append(one); // For AbsoluteSizeSpan, the flag must be set to 0, otherwise, it will apply this span to until end of text word3.setSpan(new AbsoluteSizeSpan(22), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE); // For BackgroundColorSpanSpan, the flag must be set to 0, otherwise, it will apply this span to end of text word3.setSpan(new BackgroundColorSpan(Color.DKGRAY), start, end, 0); //Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.append(two); start = end; end += two.length(); word3.setSpan(new TypefaceSpan("sans-serif"), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // TODO: sometimes, flag must be set to 0, otherwise it will apply the span to until end of text // which MIGHT has nothing to do with specific span type. word3.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.setSpan(new ScaleXSpan(0.618f), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.setSpan(new StrikethroughSpan(), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.setSpan(new ForegroundColorSpan(Color.CYAN), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.setSpan(new QuoteSpan(), start, end, 0); //Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.append(three); start = end; end += three.length(); word3.setSpan(new RelativeSizeSpan((float) Math.E), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); word3.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); textTroubles.setText(word3); // Highlight some patterns final String four = "The gap between the best software engineering " + "practice and the average practice is very wide¡ªperhaps wider " + " than in any other engineering discipline. A tool that disseminates " + "good practice would be important.¡ªFred Brooks"; final Pattern highlight = Pattern.compile("the"); final TextView textHighlight = (TextView) findViewById(R.id.text_view_font_4); SpannableString word4 = new SpannableString(four); Matcher m = highlight.matcher(word4.toString()); while (m.find()) { word4.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); word4.setSpan(new ForegroundColorSpan(Color.RED), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); word4.setSpan(new StrikethroughSpan(), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); } textHighlight.setText(word4); // Set numbers, URLs and E-mail address to be clickable with TextView#setAutoLinkMask final TextView textClickable = (TextView) findViewById(R.id.text_view_font_5); final String contact = "Email: mvp@microsoft.com\n" + "Phone: +47-24885883\n" + "Fax: +47-24885883\n" + "HTTP: www.microsoft.com/mvp.asp"; // Set the attribute first, then set the text. Otherwise, it won't work textClickable.setAutoLinkMask(Linkify.ALL); // or set 'android:autoLink' in layout xml textClickable.setText(contact); }}
The results: