很多App中都會(huì)涉及到:在TextView中設(shè)置不同顏色的字體并且部分字體會(huì)存在點(diǎn)擊事件。
在Android中主要通過(guò)ClickableSpan類來(lái)實(shí)現(xiàn)這一功能,其實(shí)這個(gè)實(shí)現(xiàn)沒(méi)有任何技巧,只不過(guò)自己在實(shí)現(xiàn)的時(shí)候遇到一個(gè)坑(坑會(huì)在下文指出)部念,特以此記錄一下。
在Google官方API文檔中這樣解釋ClickableSpan:
If an object of this type is attached to the text of a TextView with a movement method of LinkMovementMethod, the affected spans of text can be selected.? If clicked, theonClick(View)method will be called.
大致意思是:如果將該類的(ClickableSpan)對(duì)象與TextView的文本連接在一起,并且TextView設(shè)置了LinkMovementMethod方法家坎,則可以選擇受影響的文本范圍嘱能。如果需要點(diǎn)擊,則需要調(diào)用onClick(View)方法虱疏。其中的“受影響的文本”惹骂,就是你想要的有不同顏色或者有點(diǎn)擊效果的文本了。
從ClickableSpan繼承的父類來(lái)看
extends ?CharacterStyle??implements ?UpdateAppearance
?android.text.style.CharacterStyle
?android.text.style.ClickableSpan
ClickableSpan類同BackgroundColorSpan(背景色)做瞪、ForegroundColorSpan(前景色暨字體顏色)对粪、UnderlineSpan(下劃線)等類用法相似,都是為T(mén)extView下的文本設(shè)置不同Style的装蓬。在明白了ClickableSpan的作用以及出處后著拭,接下來(lái)的事情就是馬代碼了。
自定義類繼承ClickableSpan牍帚,重寫(xiě)其中的onClick(View widget)儡遮、updateDrawState(TextPaint ds)方法(此處有坑!此處有坑暗赶!此處有坑鄙币!重要的事情說(shuō)三遍)。因?yàn)橹坝锌吹轿恼略谶@個(gè)方法下面去使用TextPaint下的setColor(int color)方法給部分字體設(shè)置顏色忆首,作為菜雞的我就這樣去試了爱榔,但是顏色和自己設(shè)置的卻有差別,不得不找問(wèn)題出在哪兒(還以為UI給錯(cuò)色值了.....)糙及。
查看抽象類ClickableSpan源碼:
/**
* If an object of this type is attached to the text of a TextView
* with a movement method of LinkMovementMethod, the affected spans of
* text can be selected.? If clicked, the {@link#onClick} method will
* be called.
*/
public abstract class ClickableSpan extends CharacterStyle implements UpdateAppearance{
/**
* Performs the click action associated with this span.
*/
public abstract voidonClick(View widget);
/**
* Makes the text underlined and in the link color.
*/
@Override
public void updateDrawState(TextPaint ds) {
? ? ? ? ? ds.setColor(ds.linkColor);
? ? ? ? ?ds.setUnderlineText(true);
?}
}
源碼給出的解釋是可以設(shè)置鏈接的顏色详幽,所以我猜測(cè)會(huì)不會(huì)因?yàn)樗旧硪呀?jīng)設(shè)置了一個(gè)顏色,再次設(shè)置的話就會(huì)覆蓋導(dǎo)致出現(xiàn)差別浸锨。
public class MyClickableSpan extends ClickableSpan {
? ? ? ?private String str;
? ? ? ?private Context context;
? ? ? ?pulbic MyClickabelSpan(String str, Context context){
? ? ? ? ? ? ? ? ?this.str = str;
? ? ? ? ? ? ? ? ?this.context = context;
? ? ? ?}
? ? ? @Override
? ? ? public ?void ?updateDrawState(TextPaint ?ds) {
? ? ? ? ? ? ? ? ?//ds.setColor(Color.BULE) ? 通過(guò)這里設(shè)置出來(lái)的顏色有差別
? ? ? }
? ? @Override
? ? public ?void ?onClick(View ?widget) {
? ? ? ? ? ? ? //這里的判斷是為了去掉在點(diǎn)擊后字體出現(xiàn)的背景色
? ? ? ? ? ? ? ? if(widget ?instanceof ?TextView){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ((TextView)widget).setHighlightColor(Color.TRANSPARENT);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //在這里寫(xiě)下你想要的點(diǎn)擊效果
? ? ? ? ? ? ? ? context.startActivity(newIntent(context,AgreementActivity.class));
? ? ?}
}
在定義好類之后唇聘,就可以在TextView上進(jìn)行設(shè)置了,代碼如下:
TextView mText;
mText = (TextView) findViewById(R.id.XXX);
String str = "想要設(shè)置成不同顏色或者有點(diǎn)擊事件的字符串"
SpannableString ? span = new SpannableString(str);
ClickableSpan clickSpan = new MyClickableSpan(str, this);
span.setSpan(clickSpan, 0, str.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//在這里通過(guò)ForegroundColorSpan來(lái)給部分字體設(shè)置顏色柱搜〕倮桑可以設(shè)置成功
span.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.XXX)), 0, str.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
mText.setText("正常部分的字符串");
mText.append(span);
mText.setMovementMethod(LinkMovementMethod.getInstance()); ? //這個(gè)必須有,API對(duì)ClickableSpan類的解釋里面便提到了:在TextView設(shè)置了此方法的前提下聪蘸,才能選擇受影響的文本范圍宪肖。
通過(guò)以上的實(shí)現(xiàn),基本可以滿足TextView設(shè)置不同顏色等樣式的需求健爬。