Android中SpannableString使用(一)---如何在一個(gè)TextView中顯示不同樣式的文字

最近受到大佬的影響,決定來寫寫東西,記錄一下自己平時(shí)學(xué)習(xí)工作中遇到的一些東西。第一次在簡(jiǎn)書上寫東西,逼近還是第一次么,難免還是有一些緊張激動(dòng)。

俗話說男人就怕太快了,所以希望自己也能多堅(jiān)持堅(jiān)持,把寫東西這個(gè)事情堅(jiān)持久一點(diǎn)吧。

好了,瞎扯完了,開始。

第一篇就先寫一個(gè)Android中如何在一個(gè)TextView中給文字設(shè)置不同的樣式吧。
都知道Android開發(fā)中用于顯示文字最簡(jiǎn)單的View就是Textview了,調(diào)用setText()函數(shù)設(shè)置文字。如果你需要給同一個(gè)TextView中的文字設(shè)置不同的樣式的話,就可以使用SpannableString這個(gè)類來完成。(當(dāng)然還有很多其他的方式)

SpannableString是什么


/**

* This is the class for text whose content is immutable but to which

* markup objects can be attached and detached.

* For mutable text, see {@link SpannableStringBuilder}.

*/

public class SpannableString

extends SpannableStringInternal

implements CharSequence, GetChars, Spannable

{

public SpannableString(CharSequence source) {

super(source,0, source.length());

}

private SpannableString(CharSequence source,int start,int end) {

super(source, start, end);

}

public static SpannableString valueOf(CharSequence source) {

if (sourceinstanceof SpannableString) {

return (SpannableString) source;

}else {

return new SpannableString(source);

}

}

public void setSpan(Object what,int start,int end,int flags) {

super.setSpan(what, start, end, flags);

}

public void removeSpan(Object what) {

super.removeSpan(what);

}

public final CharSequence subSequence(int start,int end) {

return new SpannableString(this, start, end);

}

}

從SpannableString的源碼中可以看出,其實(shí)SpannableString,是CharSequence的一種。而原本的CharSequence是一串沒有樣式的字符串序列。而SpannableString就可以做到在原有的字符串序列的基礎(chǔ)上對(duì)指定位置的字符進(jìn)行裝飾。我們?cè)诮o就可以使用setText(SpannableString),SpannableString作為參數(shù),從而達(dá)到不同的顯示樣式。

創(chuàng)建一個(gè)SpannableString對(duì)象。

SpannableString spannableString = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");

怎么使用SpannableString設(shè)置字體樣式

public void setSpan(Object what, int start, int end, int flags) {
        super.setSpan(what, start, end, flags);
 }
textview.setText(spannableString);

這個(gè)方法有四個(gè)參數(shù):

  1. Object what:對(duì)SpannableString進(jìn)行裝飾的span,可以理解成不同的各種樣式(常見span有:ForegroundColorSpan,BackgroudColorSpan,ClickableSpan,URLSpan,MaskFilterSpan,RelativeSizeSpan等等,后面回給出集中實(shí)例樣式)


    各種Span
  2. int start:使用樣式效果的起始下標(biāo)位置

  3. int end: 使用樣式效果的結(jié)束下標(biāo)位置

  4. int flags:決定開始和結(jié)束下標(biāo)是否包含的標(biāo)志位。簡(jiǎn)單點(diǎn)就是一個(gè)使用樣式的一個(gè)區(qū)間。這個(gè)參數(shù)用四個(gè)固定的值可以讓我們選擇

    • SPAN_INCLUSIVE_EXCLUSIVE:包括開始下標(biāo),但不包括結(jié)束下標(biāo)。區(qū)間表示:[start,end)
    • SPAN_EXCLUSIVE_INCLUSIVE:不包括開始下標(biāo),但包括結(jié)束下標(biāo)。區(qū)間表示:(start,end]
    • SPAN_INCLUSIVE_INCLUSIVE:既包括開始下標(biāo),又包括結(jié)束下標(biāo)。區(qū)間表示:[start,end]
    • SPAN_EXCLUSIVE_EXCLUSIVE:不包括開始下標(biāo),也不包括結(jié)束下標(biāo)。區(qū)間表示:(start,end)

不同的Span樣式實(shí)例

先看一張效果


不同的Span效果
ForegroundColorSpan:前景色,也就是給指定的文字上色。

效果對(duì)應(yīng)上圖的第一個(gè)TextView
ForegroundColorSpan參數(shù):@ColorInt int color。只需要傳入顏色即可

SpannableString spannableString = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundColorSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv1.setText(spannableString);
BackgroundColorSpan:背景色,也就是給指定的文字的背景上色。

BackgroundColorSpan參數(shù):@ColorInt int color。只需要傳入顏色即可

SpannableString spannableString2 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);
spannableString2.setSpan(backgroundColorSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv2.setText(spannableString2);
MaskFilterSpan:一種模糊效果。

MaskFilterSpan參數(shù):MaskFilter filter。

SpannableString spannableString3 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
MaskFilterSpan embossMaskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{10, 10, 10}, 0.5f, 1, 1));
spannableString3.setSpan(embossMaskFilterSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);
spannableString3.setSpan(relativeSizeSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
spannableString3.setSpan(blurMaskFilterSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv3.setText(spannableString3);

而MaskFilter有兩個(gè)子類:EmbossMaskFilter和BlurMaskFilter

EmbossMaskFilter:實(shí)現(xiàn)一種浮雕的效果

public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) {
        if (direction.length < 3) {
            throw new ArrayIndexOutOfBoundsException();
        }
        native_instance = nativeConstructor(direction, ambient, specular, blurRadius);
    }

從EmbossMaskFilter的源碼中可以看見它需要4個(gè)參數(shù)

  • float[] direction:一個(gè)長(zhǎng)度為3的float數(shù)組,定義出光源的方向
  • float ambient:取值范圍0~1,定義環(huán)境光的強(qiáng)度
  • float specular:反射系數(shù)
  • float blurRadius:必須大于0,模糊半徑

BlurMaskFilter:實(shí)現(xiàn)一種模糊的效果

/**
* Create a blur maskfilter.
*
* @param radius The radius to extend the blur from the original mask. Must be > 0.
* @param style  The Blur to use
* @return       The new blur maskfilter
*/
public BlurMaskFilter(float radius, Blur style) {
    native_instance = nativeConstructor(radius, style.native_int);
}

從BlurMaskFilter的源碼中可以看見它需要2個(gè)參數(shù)

  • float radius:模糊半徑
  • Blur style:模糊樣式,四個(gè)值可選
public enum Blur {
        /**
         * Blur inside and outside the original border.
         */
        NORMAL(0),

        /**
         * Draw solid inside the border, blur outside.
         */
        SOLID(1),

        /**
         * Draw nothing inside the border, blur outside.
         */
        OUTER(2),

        /**
         * Blur inside the border, draw nothing outside.
         */
        INNER(3);
        
        Blur(int value) {
            native_int = value;
        }
        final int native_int;
    }

BlurMaskFilter.Blur.NORMAL:內(nèi)外模糊
BlurMaskFilter.Blur.OUTER:外部模糊
BlurMaskFilter.Blur.INNER:內(nèi)部模糊
BlurMaskFilter.Blur.SOLID:內(nèi)部加粗,外部模糊

RelativeSizeSpan:改變字體的相對(duì)大小。
SpannableString spannableString4 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
RelativeSizeSpan relativeSizeSpan2 = new RelativeSizeSpan(2f);
spannableString4.setSpan(relativeSizeSpan2, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv4.setText(spannableString4);
ScaleXSpan:相對(duì)X軸對(duì)字體的寬度進(jìn)行縮放。
SpannableString spannableString5 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ScaleXSpan scaleXSpan= new ScaleXSpan(2f);
spannableString5.setSpan(scaleXSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv5.setText(spannableString5);
TextAppearanceSpan:設(shè)置文字樣式,通過style資源設(shè)置。
SpannableString spannableString6 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(this, android.R.style.TextAppearance_Material);
spannableString6.setSpan(textAppearanceSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv6.setText(spannableString6);
UnderlineSpan:給文字添加下劃線。
SpannableString spannableString7 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString7.setSpan(underlineSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv7.setText(spannableString7);
StrikethroughSpan:給文字添加刪除線。
SpannableString spannableString8 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString8.setSpan(strikethroughSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv8.setText(spannableString8);
URLSpan:給文字添加一個(gè)超鏈接,點(diǎn)擊跳轉(zhuǎn)至指定的url。
SpannableString spannableString9 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
URLSpan urlSpan = new URLSpan("https://www.baidu.com");
spannableString9.setSpan(urlSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv9.setMovementMethod(LinkMovementMethod.getInstance());
tv9.setText(spannableString9);
clickableSpan:給文字添加一個(gè)點(diǎn)擊區(qū)域。ClickableSpan是一個(gè)抽象類,實(shí)現(xiàn)可點(diǎn)擊效果,操作時(shí)可以重寫onClick方法實(shí)現(xiàn)點(diǎn)擊事件
SpannableString spannableString10 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ClickableSpan clickableSpan = new ClickableSpan() {
     @Override
     public void onClick(View widget) {
          Toast.makeText(MyCourseActivity.this, "SpannableString", Toast.LENGTH_SHORT).show();
     }
     @Override
     public void updateDrawState(TextPaint ds) {
          ds.setUnderlineText(false);
     }
};
spannableString10.setSpan(clickableSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv10.setMovementMethod(LinkMovementMethod.getInstance());
tv10.setText(spannableString10);

(注意:這里我也只是例舉了幾種簡(jiǎn)單的效果,還有很多就不一一展示了。同時(shí)這些各種各樣的Span也是可以組合使用,實(shí)現(xiàn)一些比較復(fù)雜的樣式,一切只需要按照需求進(jìn)行使用即可。)

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

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

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