Android的TextView文本:用SpannableString打造絢麗多彩的顯示效果
前言
TextView是 Android 中最簡(jiǎn)單、最常見的文字控件,幾乎每個(gè)頁(yè)面都有 TextView 的身影;
絕大多數(shù)情況我們用 TextView 只是單純地顯示一個(gè)文本;
但是簡(jiǎn)單的 TextView 也能千變?nèi)f化顯示出各種效果,這一切都要?dú)w功于 SpannableString;
今天我們就來講解;
一、SpannableString介紹
SpannableString其實(shí)和String一樣,都是一種字符串類型,同樣TextView也可以直接設(shè)置SpannableString作為顯示文本,不同的是SpannableString可以通過使用其方法setSpan方法實(shí)現(xiàn)字符串各種形式風(fēng)格的顯示,重要的是可以指定設(shè)置的區(qū)間,也就是為字符串指定下標(biāo)區(qū)間內(nèi)的子字符串設(shè)置格式;
setSpan(Object what, int start, int end, int flags)方法需要用戶輸入四個(gè)參數(shù),what表示設(shè)置的格式是什么,可以是前景色、背景色也可以是可點(diǎn)擊的文本等等,start表示需要設(shè)置格式的子字符串的起始下標(biāo),同理end表示終了下標(biāo),flags屬性就有意思了,共有四種屬性:
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE 從起始下標(biāo)到終了下標(biāo),包括起始下標(biāo)
 - Spanned.SPAN_INCLUSIVE_INCLUSIVE 從起始下標(biāo)到終了下標(biāo),同時(shí)包括起始下標(biāo)和終了下標(biāo)
 - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 從起始下標(biāo)到終了下標(biāo),但都不包括起始下標(biāo)和終了下標(biāo)
 - Spanned.SPAN_EXCLUSIVE_INCLUSIVE 從起始下標(biāo)到終了下標(biāo),包括終了下標(biāo)
 
SpannableString可以實(shí)現(xiàn)的效果
- BackgroundColorSpan 背景色;
 - ClickableSpan 文本可點(diǎn)擊,有點(diǎn)擊事件;
 - ForegroundColorSpan 文本顏色(前景色);
 - MaskFilterSpan 修飾效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter);
 - MetricAffectingSpan 父類,一般不用;
 - RasterizerSpan 光柵效果;
 - StrikethroughSpan 刪除線(中劃線);
 - SuggestionSpan 相當(dāng)于占位符;
 - UnderlineSpan 下劃線;
 - AbsoluteSizeSpan 絕對(duì)大小(文本字體);
 - DynamicDrawableSpan 設(shè)置圖片,基于文本基線或底部對(duì)齊;
 - ImageSpan 圖片;
 - RelativeSizeSpan 相對(duì)大小(文本字體);
 - ReplacementSpan 父類,一般不用;
 - ScaleXSpan 基于x軸縮放;
 - StyleSpan 字體樣式:粗體、斜體等;
 - SubscriptSpan 下標(biāo)(數(shù)學(xué)公式會(huì)用到);
 - SuperscriptSpan 上標(biāo)(數(shù)學(xué)公式會(huì)用到);
 - TextAppearanceSpan 文本外貌(包括字體、大小、樣式和顏色);
 - TypefaceSpan 文本字體;
 - URLSpan 文本超鏈接;
 
二、效果實(shí)現(xiàn)
1、絕對(duì)大小
AbsoluteSizeSpan 就是構(gòu)建絕對(duì)大小的類,它有兩個(gè)參數(shù),第一個(gè)表示字體大小,第二個(gè)表示是否使用 DIP,false 的話單位就是 px,true 的話單位就是 dp;
- SpannableString ss = new SpannableString(txAbsoluteSize.getText());
 - ss.setSpan(new AbsoluteSizeSpan(12, true), 2, 4, SPAN_EXCLUSIVE_EXCLUSIVE);
 - txAbsoluteSize.setText(ss);
 
2、相對(duì)大小
相對(duì)字體大小就簡(jiǎn)單一些了,只需要傳入一個(gè)字體相對(duì)大小,比如我們傳入了 1.5,中間兩個(gè)字就變成了原始字體的 1.5 倍大;
- SpannableString ss = new SpannableString(txRelativeSize.getText());
 - ss.setSpan(new RelativeSizeSpan(1.5f), 2, 4, SPAN_EXCLUSIVE_EXCLUSIVE);
 - txRelativeSize.setText(ss);
 
3、前景色
- SpannableString ss = new SpannableString(txForegroundColor.getText());
 - ss.setSpan(new ForegroundColorSpan(Color.BLUE), 0, txForegroundColor.getText().length(), SPAN_EXCLUSIVE_EXCLUSIVE);
 - txForegroundColor.setText(ss);
 
4、背景色
- SpannableString ss = new SpannableString(txBackgroundColor.getText());
 - ss.setSpan(new BackgroundColorSpan(Color.LTGRAY), 0,
 - txBackgroundColor.getText().length(), SPAN_EXCLUSIVE_EXCLUSIVE);
 - txBackgroundColor.setText(ss);
 
5、加粗和傾斜
粗體、斜體、粗斜體對(duì)應(yīng)的常量是:Typeface.BOLD、Typeface.ITALIC、Typeface.BOLD_ITALIC
- SpannableString ss = new SpannableString(txBord.getText());
 - ss.setSpan(new StyleSpan(Typeface.BOLD), 0, txBord.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txBord.setText(ss);
 
6、刪除線
刪除線用到的類是 StrikethroughSpan,沒有參數(shù);
- SpannableString ss = new SpannableString(txDeleteLine.getText());
 - ss.setSpan(new StrikethroughSpan(), 0, txDeleteLine.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txDeleteLine.setText(ss);
 
7、點(diǎn)擊事件添加ClickableSpan的使用
- SpannableString spannableString = new SpannableString("要點(diǎn)擊的內(nèi)容");
 - spannableString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.theme_default)), 0, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);//修改字體顏色
 - ClickableSpan clickableSpan = new ClickableSpan() {//添加點(diǎn)擊
 - @Override
 - public void onClick(View widget) {
 - onMyCommentClick(widget);//點(diǎn)擊事件
 - }
 - @Override
 - public void updateDrawState(TextPaint ds) {
 - //去除連接下劃線
 - ds.setColor(ds.linkColor);
 - ds.setUnderlineText(false);
 - }
 - };
 - spannableString.setSpan(clickableSpan, 0, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
 - txtView.setMovementMethod(LinkMovementMethod.getInstance());;//這句必須添加,否則點(diǎn)擊沒反應(yīng)
 - txtView.setText(spannableString);
 
8、下劃線
下劃線用到的類是 UnderlineSpan
- SpannableString ss = new SpannableString(txUnderLine.getText());
 - ss.setSpan(new UnderlineSpan(), 0, txUnderLine.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txUnderLine.setText(ss);
 
9、插入圖片或者表情
SpannableString 除了可以像前面那樣把文字變大變小變長(zhǎng)變色,還可以把一部分文字變成圖片,承載圖片的是 Drawable 對(duì)象,而實(shí)現(xiàn)這個(gè)效果的就是 ImageSpan;
- SpannableString ss = new SpannableString(str);
 - ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
 - ss.setSpan(span, 0, str.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
 
10、文字的上標(biāo)和下標(biāo)
- SpannableString ss = new SpannableString(txSubSuperScript.getText());
 - ss.setSpan(new SuperscriptSpan(), 2, 3, SPAN_EXCLUSIVE_EXCLUSIVE);
 - ss.setSpan(new SubscriptSpan(), 5, 6, SPAN_EXCLUSIVE_EXCLUSIVE);
 - txSubSuperScript.setText(ss);
 
11、超鏈接形式
SpannableString 支持 6 中超鏈接形式,分別是:電話超鏈接、郵件超鏈接、網(wǎng)址超鏈接、短信超鏈接、彩信超鏈接、地圖超鏈接;
11.1.電話超鏈接
類:URLSpan,實(shí)際上6種超鏈接都是使用 URLSpan 構(gòu)建的,只是構(gòu)造函數(shù)傳入的鏈接格式不一樣, 電話超鏈接傳入的是 tel: 開頭,后面接要撥打的電話號(hào)碼,點(diǎn)擊后就會(huì)自動(dòng)跳轉(zhuǎn)撥打電話;
- SpannableString ss = new SpannableString(txTelUrl.getText());
 - ss.setSpan(new URLSpan("tel:02512345678"), 0, txTelUrl.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txTelUrl.setText(ss);
 - txTelUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
11.2.郵件超鏈接
郵件超鏈接是以 mailto: 開頭,后面接郵箱地址。點(diǎn)擊后就會(huì)自動(dòng)跳轉(zhuǎn)郵件 app;
- SpannableString ss = new SpannableString(txMailUrl.getText());
 - ss.setSpan(new URLSpan("mailto:xxx@google.com"), 0, txMailUrl.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txMailUrl.setText(ss);
 - txMailUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
11.3.網(wǎng)址超鏈接
網(wǎng)址超鏈接是以 http:// 或 https:// 開頭,后面接網(wǎng)址,點(diǎn)擊后跳轉(zhuǎn)瀏覽器 app,同樣如果有多個(gè)瀏覽器,需要作出選擇;
- SpannableString ss = new SpannableString(txWebUrl.getText());
 - ss.setSpan(new URLSpan("http://www.baidu.com"), 0, txWebUrl.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txWebUrl.setText(ss);
 - txWebUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
11.4.短信超鏈接
短信超鏈接是以 sms: 開頭,后面接手機(jī)號(hào)碼,點(diǎn)擊后跳轉(zhuǎn)系統(tǒng)短信 app;
- SpannableString ss = new SpannableString(txSmsUrl.getText());
 - ss.setSpan(new URLSpan("sms:02512345678"), 0, txSmsUrl.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txSmsUrl.setText(ss);
 - txSmsUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
11.5.彩信超鏈接
彩信超鏈接是以 mms: 開頭,后面接手機(jī)號(hào)碼,點(diǎn)擊跳轉(zhuǎn)系統(tǒng)短信app;
- SpannableString ss = new SpannableString(txMmsUrl.getText());
 - ss.setSpan(new URLSpan("mms:02512345678"), 0, txMmsUrl.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txMmsUrl.setText(ss);
 - txMmsUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
11.6.地圖超鏈接
地圖超鏈接以 geo: 開頭,后面接經(jīng)緯度,點(diǎn)擊后跳轉(zhuǎn)地圖 app;
- SpannableString ss = new SpannableString(txGeoUrl.getText());
 - ss.setSpan(new URLSpan("geo:30.123456,-50.024456"), 0,
 - txGeoUrl.getText().length(), SPAN_EXCLUSIVE_EXCLUSIVE);
 - txGeoUrl.setText(ss);
 - txGeoUrl.setMovementMethod(LinkMovementMethod.getInstance());
 
12、添加項(xiàng)目符號(hào)
BulletSpan 類用于構(gòu)建項(xiàng)目符號(hào),第一個(gè)參數(shù)是項(xiàng)目符號(hào)所占的寬度,第二個(gè)參數(shù)是項(xiàng)目符號(hào)的顏色;
- SpannableString ss = new SpannableString(txBullte.getText());
 - ss16.setSpan(new BulletSpan(20, Color.RED), 0, txBullte.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txBullte.setText(ss);
 
13、文字的橫向和縱向拉伸
ScaleXSpan 類用于指定橫向拉伸的比例,我們傳 2.5 表示橫向拉伸為原來的 2.5 倍;
有了橫向拉伸,自然我們會(huì)想縱向拉伸,不好意思,不支持。因?yàn)榭v向的高度就得用 textSize 設(shè)置;
- SpannableString ss = new SpannableString(txScaleX.getText());
 - ss.setSpan(new ScaleXSpan(2.5f), 0, txScaleX.getText().length(),
 - SPAN_EXCLUSIVE_EXCLUSIVE);
 - txScaleX.setText(ss);
 
總結(jié)
EditText顯示表情包也是SpannableString,后面我們可以做個(gè)表情包自定義控件;
一起學(xué)習(xí)加油;
本文轉(zhuǎn)載自微信公眾號(hào)「Android開發(fā)編程」

























 
 
 

 
 
 
 