【API Guides】Android字串資源的格式化和樣式,guidesandroid
轉載請註明出處:http://blog.csdn.net/zhaokaiqiang1992
本文章翻譯自Android開發指導,介紹了如何對字串資源進行格式化和設定不同的樣式。
想看原文,請戳這裡
- 字串資源的格式化和樣式
- 小心撇號和引用號的坑
- 格式化字串
- 用HTML添加樣式
字串資源的格式化和樣式小心撇號和引用號的坑
如果我們的字串資源裡面有撇號(‘),那麼我們必須加上轉移字元,變成這個樣子(\’),或者是在字串的外麵包裹上一對引號。我們下面看個例子:
<string name="good_example">This\'ll work</string><string name="good_example_2">"This'll also work"</string><string name="bad_example">This doesn't work</string> <!-- 會造成編譯錯誤 -->
如果你的字串有雙引號,那麼你必須用(\”)代替。在字串外麵包裹單引號是沒有作用的。
<string name="good_example">This is a \"good string\".</string><string name="bad_example">This is a "bad string".</string> <!-- 引號會被忽略;最後的顯示結果就是: This is a bad string. --><string name="bad_example_2">'This is another "bad string".'</string> <!-- 會造成編譯錯誤 -->
格式化字串
如果你需要用 String.format(String, Object…) 這種方式來格式化字串,那麼你可以把你的格式化參數放在string的資源檔裡面,我們以下面的這個資源舉個例子:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
在上面這個例子裡面,有兩個格式化參數,%1s是一個字串參數,d 是一個小數參數。你可以像下面這樣格式化字串:
Resources res = getResources();String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
用HTML添加樣式
你可以使用HTML標籤為你的字串添加樣式,下面我們舉個例子:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="welcome">Welcome to <b>Android</b>!</string></resources>
支援的HTML元素標籤包括:
有些時候,你可能想建立即帶有格式化參數,又可以格式化樣式的字串資源,通常來說,這不會起作用,因為直接使用 String.format(String, Object…) 會把所有的樣式資訊全部過濾掉。所以在格式化之後,需要用Html.fromHtml()把HTML標籤的餓效果顯示出來:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string></resources>
在這個格式化字串裡面,標籤被添加進去了。注意左括弧被HTML逸出字元串 < 代替了。
- 這樣格式化字串就和普通的一樣了,但是我們還需要調用Html.fromHtml()把HTML標籤轉換成樣式文本
Resources res = getResources();String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);CharSequence styledText = Html.fromHtml(text);
- 因為Html.fromHtml()會把所有的HTML實體都格式化了,所以一定要把字串進行格式化,避免出現任何可能的HTML字元,可以使用TextUtil.htmlEncode(username)完成。比如說,如果你要給 String.format() 傳遞一個帶有”<”或者是”&”這樣類似的字元,那麼在格式化之前,我們必須去除掉這些特殊符號,這樣當我們把格式化好的字元傳遞給Html.fromHtml(text)之後,這樣字元就會按照一開始寫進去的那樣顯示出來了。我們舉個例子:
String escapedUsername = TextUtil.htmlEncode(username);Resources res = getResources();String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount);CharSequence styledText = Html.fromHtml(text);
- 用Spannables設定樣式
使用Spannables對象,我們可以設定字型的顏色和字型大小。你可以使用SpannableStringBuilder來建立自己的文本,然後使用android.text.style包裡面的類,將樣式應用起來。
我們可以使用下面的協助方法,完成建立spannable文本的大部分工作
/** * Returns a CharSequence that concatenates the specified array of CharSequence * objects and then applies a list of zero or more tags to the entire range. * * @param content an array of character sequences to apply a style to * @param tags the styled span objects to apply to the content * such as android.text.style.StyleSpan * */private static CharSequence apply(CharSequence[] content, Object... tags) { SpannableStringBuilder text = new SpannableStringBuilder(); openTags(text, tags); for (CharSequence item : content) { text.append(item); } closeTags(text, tags); return text;}/** * Iterates over an array of tags and applies them to the beginning of the specified * Spannable object so that future text appended to the text will have the styling * applied to it. Do not call this method directly. */private static void openTags(Spannable text, Object[] tags) { for (Object tag : tags) { text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK); }}/** * "Closes" the specified tags on a Spannable by updating the spans to be * endpoint-exclusive so that future text appended to the end will not take * on the same styling. Do not call this method directly. */private static void closeTags(Spannable text, Object[] tags) { int len = text.length(); for (Object tag : tags) { if (len > 0) { text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { text.removeSpan(tag); } }}
下面這段代碼示範了我們應該如何使用這些方法,來完成我們的效果,比如說粗體、斜體和顏色等。你也可以參考這種做法,來完成其他的文本樣式
/** * Returns a CharSequence that applies boldface to the concatenation * of the specified CharSequence objects. */public static CharSequence bold(CharSequence... content) { return apply(content, new StyleSpan(Typeface.BOLD));}/** * Returns a CharSequence that applies italics to the concatenation * of the specified CharSequence objects. */public static CharSequence italic(CharSequence... content) { return apply(content, new StyleSpan(Typeface.ITALIC));}/** * Returns a CharSequence that applies a foreground color to the * concatenation of the specified CharSequence objects. */public static CharSequence color(int color, CharSequence... content) { return apply(content, new ForegroundColorSpan(color));}
下面的代碼則示範了如何使用方法鏈來讓個別的單詞產生不同的文本樣式:
// Create an italic "hello, " a red "world",// and bold the entire sequence.CharSequence text = bold(italic(res.getString(R.string.hello)), color(Color.RED, res.getString(R.string.world)));