1. 程式人生 > >Android -- SpannableString 實現富文字效果用法全解析

Android -- SpannableString 實現富文字效果用法全解析

先給你們看一下執行效果:

文末有Demo地址,感興趣的可以下載執行一下。

SpannableString 實現了CharSequence 和 Spannable 類 ,是字串的一種,所以其例項物件可以作為textvie.setText()的實參。
另外為SpannableString 物件通過setSpan() 方法為其設定特殊效果。

setSpan(Object what, int start, int end, int flags)方法有四個引數,what表示設定的特殊效果是什麼,start表示需要設定格式的子字串的起始下標,同理end表示終了下標,flags屬性有4種取值,影響設定的上標和下標,四種取值的如下:

Spanned.SPAN_INCLUSIVE_EXCLUSIVE 包括起始下標,不包括終止下標
Spanned.SPAN_INCLUSIVE_INCLUSIVE 包括起始下標,也包括終止下標
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 不包括起始下標,也不包括終止下標
Spanned.SPAN_EXCLUSIVE_INCLUSIVE 不包括起始下標,包括終止下標

本文實現的所有效果如下:

 ForegroundColorSpan : 文字顏色
 BackgroundColorSpan : 文字背景色
 StrikethroughSpan : 刪除線
 UnderlineSpan : 下劃線
 AbsoluteSizeSpan : 文字字型(絕對大小)
 RelativeSizeSpan : 相對大小(文字字型)
 ScaleXSpan : 基於x軸縮放
 TypefaceSpan : 文字字型
 StyleSpan : 字型樣式:粗體、斜體等
 SubscriptSpan : 下標(數學公式會用到)
 SuperscriptSpan : 上標(數學公式會用到)
 URLSpan : 文字超連結
 ClickableSpan : 點選事件
 ImageSpan : 圖片
 IconMarginSpan,DrawableMarginSpan  : 帶偏移圖片
 DynamicDrawableSpan:動態指定圖片
 MaskFilterSpan : 修飾效果,模糊(BlurMaskFilter);
浮雕;

1.ForegroundColorSpan : 文字顏色BackgroundColorSpan : 文字背景色

        SpannableString spannableString01 = new SpannableString("文字顏色為紫色,背景色為藍色");
        ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#EE38FB"));
        BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor
("#40C3FF")); spannableString01.setSpan(foregroundColorSpan, 5, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); spannableString01.setSpan(backgroundColorSpan, 12, 14, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); tv_01.setText(spannableString01);

2.StrikethroughSpan : 刪除線 UnderlineSpan : 下劃線

        SpannableString spannableString02 = new SpannableString("文字刪除線,下劃線");
        StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
        UnderlineSpan underlineSpan = new UnderlineSpan();
        spannableString02.setSpan(strikethroughSpan, 2, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString02.setSpan(underlineSpan, 6, 9, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_02.setText(spannableString02);

3.AbsoluteSizeSpan : 文字字型(絕對大小)RelativeSizeSpan : 相對大小(文字字型)

        SpannableString spannableString03 = new SpannableString("文字絕對大小,相對大小");
        AbsoluteSizeSpan absoluteSizeSpan01 = new AbsoluteSizeSpan(14, true);
        AbsoluteSizeSpan absoluteSizeSpan02 = new AbsoluteSizeSpan(11, true);
        AbsoluteSizeSpan absoluteSizeSpan03 = new AbsoluteSizeSpan(6, true);
        RelativeSizeSpan relativeSizeSpan01 = new RelativeSizeSpan(1.2f);
        RelativeSizeSpan relativeSizeSpan02 = new RelativeSizeSpan(0.8f);
        RelativeSizeSpan relativeSizeSpan03 = new RelativeSizeSpan(1.0f);
        spannableString03.setSpan(absoluteSizeSpan01, 2, 3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString03.setSpan(absoluteSizeSpan02, 3, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString03.setSpan(absoluteSizeSpan03, 4, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString03.setSpan(relativeSizeSpan01, 7, 8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString03.setSpan(relativeSizeSpan02, 8, 9, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString03.setSpan(relativeSizeSpan03, 9, 10, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_03.setText(spannableString03);

4.ScaleXSpan : 基於x軸縮放

        SpannableString spannableString04 = new SpannableString("基於X軸縮放");
        ScaleXSpan scaleXSpan = new ScaleXSpan(2.4f);
        spannableString04.setSpan(scaleXSpan, 2, spannableString04.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_04.setText(spannableString04);

5.TypefaceSpan : 文字字型

        SpannableString spannableString05 = new SpannableString("字型:monospace,字型:serif,\n字型:sans-serif");
        TypefaceSpan typefaceSpan01 = new TypefaceSpan("monospace");
        TypefaceSpan typefaceSpan02 = new TypefaceSpan("serif");
        TypefaceSpan typefaceSpan03 = new TypefaceSpan("sans-serif");
        spannableString05.setSpan(typefaceSpan01, 3, 11, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString05.setSpan(typefaceSpan02, 16, 21, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString05.setSpan(typefaceSpan03, 26, spannableString05.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_05.setText(spannableString05);

6.StyleSpan : 字型樣式:粗體、斜體等

        SpannableString spannableString06 = new SpannableString("粗體,斜體,粗斜體");
        StyleSpan styleSpan01 = new StyleSpan(Typeface.BOLD);
        StyleSpan styleSpan02 = new StyleSpan(Typeface.ITALIC);
        StyleSpan styleSpan03 = new StyleSpan(Typeface.BOLD_ITALIC);
        spannableString06.setSpan(styleSpan01, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString06.setSpan(styleSpan02, 3, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString06.setSpan(styleSpan03, 6, 9, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_06.setText(spannableString06);

7. SubscriptSpan : 下標 SuperscriptSpan : 上標

        SpannableString spannableString07 = new SpannableString("上標:X2,下標: H2O");
        SuperscriptSpan superscriptSpan = new SuperscriptSpan();
        SubscriptSpan subscriptSpan = new SubscriptSpan();
        spannableString07.setSpan(superscriptSpan, 4, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString07.setSpan(subscriptSpan, 11, 12, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_07.setText(spannableString07);

從前面的圖可以看出上標和下標字型並不會變小,所以我們只需要再用RelativeSizeSpan 或 AbsoluteSizeSpan 設定一下就可以了。

8.URLSpan : 文字超連結

超文字連結點選後會使用預設瀏覽器跳轉到指定的網站。必須呼叫setMovementMethod(),否則不生效。

        SpannableString spannableString08 = new SpannableString("文字超連結:我的部落格");
        URLSpan urlSpan = new URLSpan("http://blog.csdn.net/wyg1230");
        spannableString08.setSpan(urlSpan, 6, 10, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_08.setMovementMethod(LinkMovementMethod.getInstance());
        tv_08.setText(spannableString08);

9. ClickableSpan : 點選事件

ClickableSpan 需要複寫其中的onClick()方法,其實URLSpan就是繼承自ClickableSpan並在onClick方法裡面實現了跳轉邏輯。必須呼叫setMovementMethod(),否則不生效。

        SpannableString spannableString09 = new SpannableString("點選事件:請點選這一部分");
        ClickableSpan clickableSpan = new MyClickableSpan();
        spannableString09.setSpan(clickableSpan, 5, 12, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_09.setMovementMethod(LinkMovementMethod.getInstance());
        tv_09.setText(spannableString09);
    public class MyClickableSpan extends ClickableSpan {

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(Color.GREEN);//設定字型顏色
            ds.setUnderlineText(false);//設定無下劃線
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, "點選了Clickable", Toast.LENGTH_SHORT).show();
        }
    }

10. ImageSpan : 圖片

        SpannableString spannableString10 = new SpannableString("ImageSpan..");
        ImageSpan imageSpan = new ImageSpan(this, R.drawable.pic);
        spannableString10.setSpan(imageSpan, 9, 11, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_10.setText(spannableString10);

11. IconMarginSpan,DrawableMarginSpan : 帶偏移圖片

        IconMarginSpan,DrawableMarginSpan 這兩個沒啥區別,一個傳Bitmap ,一個傳Drawable
        SpannableString spannableString11 = new SpannableString("IconMarginSpan..");
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
        IconMarginSpan iconMarginSpan = new IconMarginSpan(bitmap, 100);
        spannableString11.setSpan(iconMarginSpan, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);//只能以0開始
        tv_11.setText(spannableString11);

12.DynamicDrawableSpan:動態指定圖片

在建構函式可以傳參指定對齊方式:

DynamicDrawableSpan.ALIGN_BASELINE DynamicDrawableSpan.ALIGN_BOTTOM

       SpannableString spannableString12 = new SpannableString("DynamicDrawableSpan..");
        DynamicDrawableSpan drawableSpan = new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {
            @Override
            public Drawable getDrawable() {
                Drawable d = getResources().getDrawable(R.drawable.pic);
                d.setBounds(0, 0, 200, 150);
                return d;
            }
        };
        spannableString12.setSpan(drawableSpan, spannableString12.length() - 3, spannableString12.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_12.setText(spannableString12);

13.MaskFilterSpan : 修飾效果:模糊(BlurMaskFilter);浮雕;

浮雕效果必須關閉硬體加速。

        SpannableString spannableString13 = new SpannableString("模糊效果,浮雕效果");
        MaskFilterSpan maskFilterSpan01 = new MaskFilterSpan(new BlurMaskFilter(5, BlurMaskFilter.Blur.OUTER));
        MaskFilterSpan maskFilterSpan02 = new MaskFilterSpan(new EmbossMaskFilter(new float[]{2, 3, 6}, 3.0f, 12, 16));
        spannableString13.setSpan(maskFilterSpan01, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString13.setSpan(maskFilterSpan02, 4, 9, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        tv_13.setLayerType(View.LAYER_TYPE_SOFTWARE, null);//關閉硬體加速。浮雕效果才能有效
        tv_13.setText(spannableString13);