一脑蠕、前言:
我們?cè)陂_發(fā)中,經(jīng)常遇到一段文本跪削,需要單獨(dú)給它部分文字設(shè)置不同的樣式谴仙,有的文字設(shè)置為粗體,有的文字設(shè)置特殊的顏色碾盐,有的地方要加入表情晃跺,遇到數(shù)學(xué)公式還可能要設(shè)置上下標(biāo),這時(shí)候該怎么辦呢毫玖?
有的人會(huì)采用不同的 TextView掀虎,這樣就可以完美解決了凌盯。先不說這個(gè)方法行不行得通,事實(shí)上烹玉,若采用這種方式驰怎,當(dāng)碰上一段文字需要設(shè)置非常多的樣式時(shí),光是這一堆TextView就夠浪費(fèi)資源的了二打,布局還復(fù)雜县忌,也不利于維護(hù),因此這種方式一般不會(huì)被采用继效。
那么有其他辦法嗎症杏?有,并且還很簡(jiǎn)單瑞信,今天介紹的這個(gè)SpannableString就是用來解決這個(gè)問題的鸳慈。
xml 代碼片段:
<TextView
android:id="@+id/tv_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="要變色的值"
/>
第一種方法:
//方法一:
TextView tvValue = findViewById(R.id.tv_value);
String str="默認(rèn)顏色<font color='#FF0000'><small>紅顏色
</small></font>";
tvValue.setTextSize(18);
tvValue.setText(Html.fromHtml(str));
第二種方法:
采用 SpannableString實(shí)現(xiàn)
二、 SpannableString使用:
1喧伞、SpannableString走芋、SpannableStringBuilder與String的關(guān)系
首先SpannableString、SpannableStringBuilder基本上與String差不多潘鲫,也是用來存儲(chǔ)字符串翁逞,但它們倆的特殊就在于有一個(gè)SetSpan()函數(shù),能給這些存儲(chǔ)的String添加各種格式或者稱樣式(Span)溉仑,將原來的String以不同的樣式顯示出來挖函,比如在原來String上加下劃線、加背景色浊竟、改變字體顏色怨喘、用圖片把指定的文字給替換掉,等等振定。所以必怜,總而言之,SpannableString后频、SpannableStringBuilder與String一樣梳庆, 首先也是傳字符串,但SpannableString卑惜、SpannableStringBuilder可以對(duì)這些字符串添加額外的樣式信息膏执,但String則不行。
注意:如果這些額外信息能被所用的方式支持露久,比如將SpannableString傳給TextView更米;也有對(duì)這些額外信息不支持的,比如前一章講到的Canvas繪制文字毫痕,對(duì)于不支持的情況征峦,SpannableString和SpannableStringBuilder就是退化為String類型纸巷,直接顯示原來的String字符串,而不會(huì)再顯示這些附加的額外信息眶痰。
2瘤旨、SpannableString與SpannableStringBuilder區(qū)別
它們的區(qū)別在于 SpannableString像一個(gè)String一樣,構(gòu)造對(duì)象的時(shí)候傳入一個(gè)String竖伯,之后再無法更改String的內(nèi)容存哲,也無法拼接多個(gè) SpannableString;而SpannableStringBuilder則更像是StringBuilder七婴,它可以通過其append()方法來拼接多個(gè)String祟偷;
3、創(chuàng)建方式
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
設(shè)置
spannableString.setSpan(Object what, int start, int end, int flags);
這里講解一下幾個(gè)參數(shù)的意義:
- what:對(duì)SpannableString進(jìn)行潤(rùn)色的各種Span打厘;
- int:需要潤(rùn)色文字段開始的下標(biāo)修肠;
- end:需要潤(rùn)色文字段結(jié)束的下標(biāo);
- flags:決定開始和結(jié)束下標(biāo)是否包含的標(biāo)志位户盯,有四個(gè)參數(shù)可選
- SPAN_INCLUSIVE_EXCLUSIVE:包括開始下標(biāo)嵌施,但不包括結(jié)束下標(biāo)
- SPAN_EXCLUSIVE_INCLUSIVE:不包括開始下標(biāo),但包括結(jié)束下標(biāo)
- SPAN_INCLUSIVE_INCLUSIVE:既包括開始下標(biāo)莽鸭,又包括結(jié)束下標(biāo)
- SPAN_EXCLUSIVE_EXCLUSIVE:不包括開始下標(biāo)吗伤,也不包括結(jié)束下標(biāo)
這里涉及到一個(gè)重要的角色,就是各種各樣的span硫眨,它決定我們要對(duì)文字的進(jìn)行怎樣的潤(rùn)飾足淆,而后三個(gè)參數(shù)決定潤(rùn)飾哪些文字,為了方便起見礁阁,后面的flags默認(rèn)都使用SPAN_INCLUSIVE_EXCLUSIVE模式巧号。
3、 ForegroundColorSpan
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
ForegroundColorSpan foregroundColorSpan1 = new ForegroundColorSpan(Color.GREEN);
ForegroundColorSpan foregroundColorSpan2 = new ForegroundColorSpan(Color.GREEN);
spannableString.setSpan(foregroundColorSpan1, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(foregroundColorSpan2, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- ForegroundColorSpan:前景色姥闭,也就是對(duì)文字上色丹鸿,顏色設(shè)置為GREEN,start為4泣栈,end為7卜高,應(yīng)該是“陳奕迅”三個(gè)字顯示為綠色。
- “如果” 也是綠色
注意:必須new兩個(gè)ForegroundColorSpan南片,否則只有一個(gè)地方字體變綠;
4庭敦、 BackgroudColorSpan
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);
spannableString.setSpan(backgroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
BackgroudColorSpan:與ForegroundColorSpan類似疼进,對(duì)文字背景上色
5、 AbsoluteSizeSpan
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(40, true);
spannableString.setSpan(absoluteSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
AbsoluteSizeSpan:設(shè)置字體的相絕對(duì)大小秧廉,40表示文字大小伞广,true表示單位為dip拣帽,若為false則表示px
6、 UnderlineSpan (下劃線)
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
UnderlineSpan:設(shè)置文字下劃線嚼锄,強(qiáng)調(diào)突出文字時(shí)可以使用該span
7减拭、StrikethroughSpan (中間刪除線)
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
8、 SuperscriptSpan (上標(biāo))
代碼
SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");
SuperscriptSpan superscriptSpan = new SuperscriptSpan();
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(0.8f);
spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(superscriptSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
SuperscriptSpan:設(shè)置文字為上標(biāo)
9区丑、部分文字的點(diǎn)擊事件
效果圖:
TextView tv1 = view.findViewById(R.id.tv1);
String content = " 歡迎來到SumanSoul為了更好地向用戶提供服務(wù)拧粪,未經(jīng)用戶同意,SumanSoul不會(huì)自動(dòng)收集沧侥、獲取可霎、共享或?qū)ν馓峁┯脩魝€(gè)人信息;你可以隨時(shí)查看宴杀、更正或刪除你的個(gè)人信息癣朗,SumanSoul也提供用戶注銷功能。";
tv_content.setText(content.replace(" ", ""));
SpannableStringBuilder spannableString = new SpannableStringBuilder("點(diǎn)擊查看完整「用戶協(xié)議」和「隱私政策」");
spannableString.setSpan(new TextAgreementClick(), 6, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new TextPrivacyClick(), 13, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//設(shè)置點(diǎn)擊事件旺罢,加上這句話才有效果
tv1.setMovementMethod(LinkMovementMethod.getInstance());
//設(shè)置點(diǎn)擊后的顏色為透明(有默認(rèn)背景)
tv1.setHighlightColor(BaseApplication.getInstance().getResources().getColor(R.color.transparent));
tv1.setText(spannableString);
<!-- 透明背景色-->
<color name="transparent" tools:ignore="MissingDefaultResource">#00000000</color>
下面是TextAgreementClick實(shí)現(xiàn)ClickableSpan
private class TextAgreementClick extends ClickableSpan{
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
//設(shè)置文本的顏色
ds.setColor(Color.RED);
//超鏈接形式的下劃線旷余,false 表示不顯示下劃線,true表示顯示下劃線
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
// 執(zhí)行點(diǎn)擊邏輯
}
}
三扁达、總結(jié)
- ForegroundColorSpan:前景色
- BackgroundColorSpan:背景色
- ClickableSpan:抽象類荣暮,可點(diǎn)擊效果,重寫onClick方法響應(yīng)點(diǎn)擊事件
- URLSpan:超鏈接
- MaskFilterSpan:EmbossMaskFilter浮雕效果罩驻,BlurMaskFilter模糊效果
- RelativeSpan:文字相對(duì)大小
- AbsoluteSpan:文字絕對(duì)大小
- ScaleXSpan:x軸縮放
- styleSpan:文字樣式
- TypefaceSpan:文字字體類型
- TextApearanceSpan:文字外貌
- UnderlineSpan:下劃線
- StrikeThroughSpan:刪除線
- SuperscriptSpan:上標(biāo)
- SubscriptSpan:下標(biāo)
- ImageSpan:圖片
這些Span能夠很好地幫助我們潤(rùn)色文字穗酥,以非常簡(jiǎn)單地方式獲得復(fù)雜和絢麗的文字效果,著實(shí)是開發(fā)中的一大利器惠遏,喜歡的朋友收藏備用吧砾跃。