項目中需要使用富文本來顯示消息通知,由于消息的類型多達(dá)幾十種,且這些不同類型消息顯示的文案由服務(wù)端控制,這里文案需要使用富文本來顯示不同顏色、大小、字體的文字,所幸是textView支持富文本顯示。具體實現(xiàn)方法有兩種:
一、使用HTML 標(biāo)記設(shè)置樣式
將待顯示字符串添加到strings文件中。例如:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="welcome">Welcome to<b>Android</b>!</string></resources>
支持的 HTML 標(biāo)簽包括:
<a href="...">創(chuàng)建超文本鏈接
<b>黑體字
<big>字體加大
<blockquote>從兩邊縮進(jìn)文本
<br>換行插入換行符
<cite>引用,通常是斜體
<dfn>述語定義
<div align="...">用來排版大塊HTML段落,也用于格式化表
<em>強調(diào)文本(通常是斜體加黑體)
<font size="..." color="..."face="...">設(shè)置字體大小從1到7,顏色使用名字或RGB的十六進(jìn)制值
<h1>至<h6>標(biāo)題
<i>斜體字
<img src="...">圖片
<p>創(chuàng)建一個段落
<small>字體縮小
<strike>加刪除線
<strong>加重文本(通常是斜體加黑體)
<sub>下標(biāo)字
<sup>上標(biāo)字
<tt>打字機風(fēng)格的字體
<u>下劃線
如果將帶樣式文本資源作為格式字符串。 正常情況下是行不通的,因為 String.format(String,Object...) 方法會去除字符串中的所有樣式信息。要解決這個問題只能編寫帶轉(zhuǎn)義實體的 HTML 標(biāo)簽,在完成格式設(shè)置后,這些實體可通過fromHtml(String) 恢復(fù)。 例如:
1.將您帶樣式的文本資源存儲為HTML 轉(zhuǎn)義字符串:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d newmessages</b>.</string></resources>
在這個帶格式的字符串中,添加了 <b> 元素。請注意,開括號使用 < 表示法進(jìn)行了 HTML 轉(zhuǎn)義。
2.然后照常設(shè)置字符串格式,但還要調(diào)用 fromHtml(String) 以將HTML 文本轉(zhuǎn)換成帶樣式文本:
Resources res = getResources();String text =String.format(res.getString(R.string.welcome_messages), username, mailCount);CharSequence styledText = Html.fromHtml(text);
由于 fromHtml(String) 方法將設(shè)置所有 HTML 實體的格式,因此務(wù)必要使用 htmlEncode(String) 對您用于帶格式文本的字符串中任何可能的 HTML 字符進(jìn)行轉(zhuǎn)義。 例如,如果您向 String.format() 傳遞的字符串參數(shù)可能包含“<”或“&”之類的字符,則必須在設(shè)置格式前進(jìn)行轉(zhuǎn)義,這樣在通過 fromHtml(String) 傳遞帶格式字符串時,字符就能以原始形式顯示出來。 例如:
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);
二、使用Spannable 設(shè)置樣式
Spannable 可以對顏色和字體粗細(xì)等屬性進(jìn)行樣式設(shè)置。 首先使用 SpannableStringBuilder 構(gòu)造文本內(nèi)容,然后為文本設(shè)置 android.text.style 包中定義的樣式,常見的樣式有StrikethroughSpan、StyleSpan、ForegroundColorSpan等。例如,為某段文字內(nèi)容加上帶顏色和刪除線的粗體樣式。
public CharSequence renderSpan(Stringtext, String color, boolean isBold, boolean isDelete) {
if(TextUtils.isEmpty(color)) {
color ="#272934";//默認(rèn)值
}
if(TextUtils.isEmpty(text)) {
return null;
}
SpannableStringBuilder span = new SpannableStringBuilder();
span.append(text);
if(isDelete) {
StrikethroughSpanstrikethroughSpan = new StrikethroughSpan();
span.setSpan(strikethroughSpan,0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (isBold){
StyleSpanboldStyle = new StyleSpan(Typeface.BOLD);
span.setSpan(boldStyle,0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
span.setSpan(newForegroundColorSpan(Color.parseColor(color)), 0,text.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
returnspan;
}
最后,項目中用到了格式化字符串,所以只能采取第一種方式來避免樣式信息被清除。這里遇到一個非常奇葩的坑, fromHtml(String)無法正常顯示帶<strike>標(biāo)簽的格式。解決辦法是結(jié)合使用spannable,如下:
public CharSequence renderSpan(String text,String color, boolean isBold, boolean isDelete) {
if(TextUtils.isEmpty(color)) {
color ="#272934";
}
if(TextUtils.isEmpty(text)) {
returnspan;
}
SpannableStringBuilder span = new SpannableStringBuilder();
span.append(text);
if(isDelete) {
span.insert(0, "<strike>");
span.append("</strike>");
}
if (isBold){
span.insert(0, "<b>");
span.append("</b>");
}
//span.insert(0, "<font color=/"" + color +"/">");
//span.append("</font>");
returnspan;
}
Resources res = getResources();String text = String.format(res.getString(R.string.welcome_messages),renderSpan(escapedUsername ,"",true,true));
SpannableStringBuilder OperateStr =new SpannableStringBuilder(text);
Object[]spans = operateStr.getSpans(0, operateStr.length(), Object.class);
if (spans.length > 0) {
for(Object object : spans) {
intstart = operateStr.getSpanStart(object);
intend = operateStr.getSpanEnd(object);
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
operateStr.setSpan(strikethroughSpan, start, end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
break;
}
}
這里通過其他span對象來確定樣式字符串的位置,然后采用第二種方式進(jìn)行處理。新聞熱點
疑難解答