Android“格式化TextView的简单方法

Wednesday, August 4, 2010

Easy method for formatting Android TextViews

Android TextViews don't have an easy method for changing the style of a substring of its text. You may have wanted to do something like textView.setTextColor(Color.RED, 10, 20); in order to set the 10th to the 20th characters red. I'll show you a method of making this easy to do; not just with colors, but with all sorts of styles.

Using regular HTML tags in strings

You do have a limited option to format your strings without any programmatic methods. In strings.xml, where you define your strings, you can use the simple HTML format tags  <b><i>, and  <u> for bold, italics, and underlining, respectively. For example,
<string name="text1">This text uses <b>bold</b> and <i>italics</i> by using inline tags such as <b> within the string file.</string>
A TextView with this string will appear as: This text uses  bold and  italics by using inline tags such as <b> within the string file.
Unfortunately, you cannot use any more HTML tags than that. In order to have some nice inline styles, we'll need to use  CharacterStyles. This class has many sub-classes, and allows you to do everything from changing the text appearance (like  ForegroundColorSpan, to more complicated things like making clickable links ( ClickableSpan) and images ( ImageSpan). 

CharSequences

A quick note about how this works. Skip to the next section if you don't care. TextView, along with many other Android classes which use formatted text, don't just use simple  Strings. They use  CharSequences. Get this: a  CharSequence is  more abstract than a  String; a  String is a sub-class of  CharSequence. A  CharSequencedefines a series of characters, such as a regular string, but it could also define a series of characters with formatting, such as a  SpannableString. Internally, what we will do to change the middle of a  TextView's text is to add spans to its text. More precisely, we will add  CharacterStyles to the TextView's  CharSequence (text), which is a  SpannableString.

Format text dynamically

Here's a handy utility method which will take in some text, and return the text formatted. The key is to surround the text you want with tokens such as  "##". The tokens will be removed in the returned result.
For example, if a  TextView has its text set as  "Hello, ##world##!" and you want world to be in red, call  setSpanBetweenTokens("Hello ##world##!", "##", new ForegroundColorSpan(0xFFFF0000)); will return the text  Hello, world! with  world in red. Note that you can send multiple spans as parameters to this method.

/**
 * Given either a Spannable String or a regular String and a token, apply
 * the given CharacterStyle to the span between the tokens, and also
 * remove tokens.
 * <p>
 * For example, {@code setSpanBetweenTokens("Hello ##world##!", "##",
 * new ForegroundColorSpan(0xFFFF0000));} will return a CharSequence
 * {@code "Hello world!"} with {@code world} in red.
 *
 * @param text The text, with the tokens, to adjust.
 * @param token The token string; there should be at least two instances
 *             of token in text.
 * @param cs The style to apply to the CharSequence. WARNING: You cannot
 *            send the same two instances of this parameter, otherwise
 *            the second call will remove the original span.
 * @return A Spannable CharSequence with the new style applied.
 *
 * @see http://developer.android.com/reference/android/text/style/CharacterStyle.html
 */
public static CharSequence setSpanBetweenTokens(CharSequence text,
    
String tokenCharacterStyle... cs)
{
    
// Start and end refer to the points where the span will apply
    
int tokenLen = token.length();
    
int start = text.toString().indexOf(token) + tokenLen;
    
int end = text.toString().indexOf(tokenstart);

    
if (start > -1 && end > -1)
    {
        
// Copy the spannable string to a mutable spannable string
        
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
        
for (CharacterStyle c : cs)
            
ssb.setSpan(cstartend, 0);

        
// Delete the tokens before and after the span
        
ssb.delete(endend + tokenLen);
        
ssb.delete(start - tokenLenstart);

        
text = ssb;
    }

    
return text;
}

Clickable spans

One of the spans you can set your text to is a  ClickableSpan. You may have added this and wondered why anything didn't happen when you clicked on the link. Well, you need to have one extra step to let Android know that there is a clickable link and it needs to be navigated to. You need to set a  MovementMethod to the  TextView. You can investigate this further if you wish, or you can just see the sample code to make it work below (and it is also in the sample):


// Adapted from Linkify.addLinkMovementMethod(), to make links clickable.
//
MovementMethod 
m = textView.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod))
{
    
textView.setMovementMethod(LinkMovementMethod.getInstance());
}

Sample Application

The sample application is a simple application with a few  TextViews and a  Button. The first  TextView shows how you can set a  TextView's text just by using HTML tags in  strings.xml. The second  TextView demonstrates how to change text dynamically, using the above utility method. When the button is clicked, it will first set some text red using a  ForegroundColorSpan. Second, it will set some text bold and italics using a  StyleSpan. Third, it will make a generic link by setting some text to blue, underlining it ( UnderlineSpan), and then creating an  onClick method which executes some custom code using a  ClickableSpan. The final click demonstrates both a  ForegroundColorSpan and a  RelativeSizeSpan.


Project source code -  formattedtext.zip (7.22 Kb)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值