Android—ClickableSpan

很多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

java.lang.Object

?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è)置不同顏色等樣式的需求健爬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末控乾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娜遵,更是在濱河造成了極大的恐慌蜕衡,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件设拟,死亡現(xiàn)場(chǎng)離奇詭異慨仿,居然都是意外死亡久脯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)镰吆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帘撰,“玉大人,你說(shuō)我怎么就攤上這事鼎姊÷夂停” “怎么了相赁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵相寇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我钮科,道長(zhǎng)唤衫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任绵脯,我火速辦了婚禮佳励,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛆挫。我一直安慰自己赃承,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布悴侵。 她就那樣靜靜地躺著瞧剖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪可免。 梳的紋絲不亂的頭發(fā)上抓于,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音浇借,去河邊找鬼捉撮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛妇垢,可吹牛的內(nèi)容都是我干的巾遭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闯估,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灼舍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起睬愤,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤片仿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后尤辱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體砂豌,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厢岂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阳距。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塔粒。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖筐摘,靈堂內(nèi)的尸體忽然破棺而出卒茬,到底是詐尸還是另有隱情,我是刑警寧澤咖熟,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布圃酵,位于F島的核電站,受9級(jí)特大地震影響馍管,放射性物質(zhì)發(fā)生泄漏郭赐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一确沸、第九天 我趴在偏房一處隱蔽的房頂上張望捌锭。 院中可真熱鬧,春花似錦罗捎、人聲如沸观谦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)豁状。三九已至,卻和暖如春雷激,著一層夾襖步出監(jiān)牢的瞬間替蔬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工屎暇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留承桥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓根悼,卻偏偏與公主長(zhǎng)得像凶异,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挤巡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容