作者:李旺成
時(shí)間:2016年5月14日
這個(gè) Hack 將介紹關(guān)于 TextView 格式化的相關(guān)知識(shí)。
特殊樣式文本
先來看看微博中一段文本包含不同樣式的示例:
在網(wǎng)頁上要實(shí)現(xiàn)類似上面的效果會(huì)比較簡(jiǎn)單:
網(wǎng)頁源碼:
<div class="WB_text W_f14" node-type="feed_list_content">
<a target="_blank" render="ext" suda-uatrack="key=topic_click&value=click_topic" class="a_topic" extra-data="type=topic" >#奇葩說#</a>
面對(duì)辯題
<a target="_blank" render="ext" suda-uatrack="key=topic_click&value=click_topic" class="a_topic" extra-data="type=topic" >#愛上人工智能算不算愛情#</a>
大美玲
<a target="_blank" render="ext" extra-data="type=atname" usercard="name=Daghe">@Daghe</a>
說完自己的觀點(diǎn)之后,給我們講了一個(gè)自己的故事宴合。當(dāng)思達(dá)站在路上像一個(gè)笨蛋一樣,呆呆的回頭看的時(shí)候,那種等不到的失落感充滿整個(gè)心的時(shí)候,大概這就是愛吧余爆。我不明白那個(gè)人為什么遲遲不出現(xiàn),我想
<a target="_blank" render="ext" suda-uatrack="key=topic_click&value=click_topic" class="a_topic" extra-data="type=topic" >#幫姜思達(dá)找到他#</a>夸盟。
<a suda-uatrack="key=tblog_card&value=click_title:3974797250061553:1034-video:1034%3A0a3f8741d4d5d557a14ea26facccedd2:page_102803_home:5512188486:3974797250061553:5512188486" title="秒拍視頻" action-type="feed_list_url" target="_blank"><i class="W_ficon ficon_cd_video">L</i>秒拍視頻</a>
</div>
那在 Android 中要實(shí)現(xiàn)上述效果該如何做蛾方?
使用 TextView 展示多樣式文本
一般在類微博、QQ空間這類社交 App 中使用這類多樣式文本的地方比較常見。要實(shí)現(xiàn)這些效果并不需要什么自定義控件转捕,因?yàn)?Android 里面的 TextView 已經(jīng)足以勝任作岖。(話說 TextView 一個(gè)非常常用的控件,但是可能你并不知道它所“蘊(yùn)含的能量”五芝,它的強(qiáng)大可能讓人驚訝...)
示例:
使用 Html 實(shí)現(xiàn)
先介紹一種直觀或者說使用比較簡(jiǎn)單的方法來實(shí)現(xiàn):
mTestTV1 = (TextView) findViewById(R.id.tv_test1);
String htmlText = "<a href=\"http://diy-green.github.io/\">我是鏈接</a>哈哈<font color='#ff0000'>@XXX<font>";
mTestTV1.setText(Html.fromHtml(htmlText));
很簡(jiǎn)單痘儡,兩行代碼或者一行代碼就搞定了,是的沒錯(cuò)就是用了兩個(gè) Html 標(biāo)簽(注意:TextView 只支持部分的 Html 標(biāo)簽枢步,不要當(dāng) WebView 用)沉删。
也就是說,只需兩步:
- 使用 Html 標(biāo)簽包裹目標(biāo)文本
- 將 Html.fromHtml() 方法處理過的文本賦值給 TextView
那 Html.fromHtml() 方法到底做了什么工作醉途?這里不打算介紹該方法的源碼實(shí)現(xiàn)矾瑰,我們更關(guān)心的是該方法處理后返回的對(duì)象。
public static Spanned fromHtml(String source);
Spanned 是什么隘擎?這是個(gè)接口:
public interface Spanned extends CharSequence {}
那就可以解釋為什么能夠直接將 Spanned 賦值給 TextView 的 setText(CharSequence text) 方法了殴穴。
來看下 Spanned 的繼承結(jié)構(gòu),找找它的子類什么的:
通過繼承結(jié)構(gòu)货葬,我們知道了該接口的實(shí)現(xiàn)類采幌,那么我們直接使用它的實(shí)現(xiàn)類即可。
SpannableString 實(shí)現(xiàn)
上面介紹的使用 Html 標(biāo)簽實(shí)現(xiàn)方式雖然直觀震桶,而且使用簡(jiǎn)便休傍,但是有如下不足:
- 功能局限性:并不支持所有的 Html 標(biāo)簽,有些效果不能實(shí)現(xiàn)
- 性能損耗:由于使用的是 Html 標(biāo)簽蹲姐,那么不可避免需要解析這些標(biāo)簽磨取,這是有性能損耗的
看代碼吧:
mTestTV2 = (TextView) findViewById(R.id.tv_test2);
Spannable spannableString = new SpannableString("我是不同顏色的文本,哈哈柴墩,不同顏色文本");
spannableString.setSpan(new BackgroundColorSpan(Color.RED), 1, 4, 0);
spannableString.setSpan(new ForegroundColorSpan(Color.BLUE), 5, 9, 0);
mTestTV2.setText(spannableString);
這種方式稍顯麻煩忙厌,但也還好,主要是如下兩步:
- 創(chuàng)建 SpannableString 對(duì)象
- 為不同的文本段設(shè)置不同的 “Span”
上面兩種方式的本質(zhì)是一樣的拐邪,都需要生成 Spanned 對(duì)象慰毅,只是生成的方式的差別而已。
這里就不展開對(duì) Spanned 進(jìn)行介紹扎阶,這個(gè)將會(huì)在 AndroidStudyDemo 系列 和 AndroidStudyDemo 分類 中寫一篇詳解。
小結(jié)
TextView 使用簡(jiǎn)單婶芭,但是功能非常強(qiáng)大东臀。上面介紹的兩種格式化文本的方式,可以根據(jù)實(shí)際需要選擇犀农。
項(xiàng)目地址
項(xiàng)目示例代碼:
FormatTextActivity.java
activity_format_text.xml