Android 中 TextView 部分文字有不同的顏色和部分文字點擊事件

一、前言:

我們在開發(fā)中,經(jīng)常遇到一段文本,需要單獨給它部分文字設(shè)置不同的樣式,有的文字設(shè)置為粗體,有的文字設(shè)置特殊的顏色,有的地方要加入表情,遇到數(shù)學(xué)公式還可能要設(shè)置上下標,這時候該怎么辦呢?

有的人會采用不同的 TextView,這樣就可以完美解決了。先不說這個方法行不行得通,事實上,若采用這種方式,當碰上一段文字需要設(shè)置非常多的樣式時,光是這一堆TextView就夠浪費資源的了,布局還復(fù)雜,也不利于維護,因此這種方式一般不會被采用。

那么有其他辦法嗎?有,并且還很簡單,今天介紹的這個SpannableString就是用來解決這個問題的。

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="默認顏色<font color='#FF0000'><small>紅顏色 
       </small></font>";
        tvValue.setTextSize(18);
        tvValue.setText(Html.fromHtml(str));

第二種方法:
采用 SpannableString實現(xiàn)

二、 SpannableString使用:

1、SpannableString、SpannableStringBuilder與String的關(guān)系

首先SpannableString、SpannableStringBuilder基本上與String差不多,也是用來存儲字符串,但它們倆的特殊就在于有一個SetSpan()函數(shù),能給這些存儲的String添加各種格式或者稱樣式(Span),將原來的String以不同的樣式顯示出來,比如在原來String上加下劃線、加背景色、改變字體顏色、用圖片把指定的文字給替換掉,等等。所以,總而言之,SpannableString、SpannableStringBuilder與String一樣, 首先也是傳字符串,但SpannableString、SpannableStringBuilder可以對這些字符串添加額外的樣式信息,但String則不行。

注意:如果這些額外信息能被所用的方式支持,比如將SpannableString傳給TextView;也有對這些額外信息不支持的,比如前一章講到的Canvas繪制文字,對于不支持的情況,SpannableString和SpannableStringBuilder就是退化為String類型,直接顯示原來的String字符串,而不會再顯示這些附加的額外信息。

2、SpannableString與SpannableStringBuilder區(qū)別

它們的區(qū)別在于 SpannableString像一個String一樣,構(gòu)造對象的時候傳入一個String,之后再無法更改String的內(nèi)容,也無法拼接多個 SpannableString;而SpannableStringBuilder則更像是StringBuilder,它可以通過其append()方法來拼接多個String;

image

3、創(chuàng)建方式

SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陳奕迅");

設(shè)置

spannableString.setSpan(Object what, int start, int end, int flags);

這里講解一下幾個參數(shù)的意義:

  • what:對SpannableString進行潤色的各種Span;
  • int:需要潤色文字段開始的下標;
  • end:需要潤色文字段結(jié)束的下標;
  • flags:決定開始和結(jié)束下標是否包含的標志位,有四個參數(shù)可選
  1. SPAN_INCLUSIVE_EXCLUSIVE:包括開始下標,但不包括結(jié)束下標
  2. SPAN_EXCLUSIVE_INCLUSIVE:不包括開始下標,但包括結(jié)束下標
  3. SPAN_INCLUSIVE_INCLUSIVE:既包括開始下標,又包括結(jié)束下標
  4. SPAN_EXCLUSIVE_EXCLUSIVE:不包括開始下標,也不包括結(jié)束下標

這里涉及到一個重要的角色,就是各種各樣的span,它決定我們要對文字的進行怎樣的潤飾,而后三個參數(shù)決定潤飾哪些文字,為了方便起見,后面的flags默認都使用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:前景色,也就是對文字上色,顏色設(shè)置為GREEN,start為4,end為7,應(yīng)該是“陳奕迅”三個字顯示為綠色。
  • “如果” 也是綠色
    注意:必須new兩個ForegroundColorSpan,否則只有一個地方字體變綠;

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類似,對文字背景上色

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è)置字體的相絕對大小,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è)置文字下劃線,強調(diào)突出文字時可以使用該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 (上標)

代碼

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è)置文字為上標

9、部分文字的點擊事件

效果圖:

image
        TextView tv1 = view.findViewById(R.id.tv1);
        String content = " 歡迎來到SumanSoul為了更好地向用戶提供服務(wù),未經(jīng)用戶同意,SumanSoul不會自動收集、獲取、共享或?qū)ν馓峁┯脩魝€人信息;你可以隨時查看、更正或刪除你的個人信息,SumanSoul也提供用戶注銷功能。";
        tv_content.setText(content.replace(" ", ""));
        SpannableStringBuilder spannableString = new SpannableStringBuilder("點擊查看完整「用戶協(xié)議」和「隱私政策」");
        spannableString.setSpan(new TextAgreementClick(), 6, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(new TextPrivacyClick(), 13, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        //設(shè)置點擊事件,加上這句話才有效果
        tv1.setMovementMethod(LinkMovementMethod.getInstance());
         //設(shè)置點擊后的顏色為透明(有默認背景)
       tv1.setHighlightColor(BaseApplication.getInstance().getResources().getColor(R.color.transparent));
        tv1.setText(spannableString);

  <!-- 透明背景色-->
    <color name="transparent" tools:ignore="MissingDefaultResource">#00000000</color>

下面是TextAgreementClick實現(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í)行點擊邏輯
        }
    }

三、總結(jié)

  • ForegroundColorSpan:前景色
  • BackgroundColorSpan:背景色
  • ClickableSpan:抽象類,可點擊效果,重寫onClick方法響應(yīng)點擊事件
  • URLSpan:超鏈接
  • MaskFilterSpan:EmbossMaskFilter浮雕效果,BlurMaskFilter模糊效果
  • RelativeSpan:文字相對大小
  • AbsoluteSpan:文字絕對大小
  • ScaleXSpan:x軸縮放
  • styleSpan:文字樣式
  • TypefaceSpan:文字字體類型
  • TextApearanceSpan:文字外貌
  • UnderlineSpan:下劃線
  • StrikeThroughSpan:刪除線
  • SuperscriptSpan:上標
  • SubscriptSpan:下標
  • ImageSpan:圖片

這些Span能夠很好地幫助我們潤色文字,以非常簡單地方式獲得復(fù)雜和絢麗的文字效果,著實是開發(fā)中的一大利器,喜歡的朋友收藏備用吧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容