Android 使用SpannableString在TextView中插入表情、超連結、文字變大、加粗

F-Fan發表於2016-06-28




本文轉載自:http://www.jianshu.com/p/84067ad289d2

效果圖集合:

這裡寫圖片描述



首先我們先來了解SpannableString

SpannableString其實和String一樣,都是一種字串型別,同樣TextView也可以直接設定SpannableString作為顯示文字,不同的是SpannableString可以通過使用其方法setSpan方法實現字串各種形式風格的顯示,重要的是可以指定設定的區間,也就是為字串指定下標區間內的子字串設定格式。


setSpan(Object what, int start, int end, int flags)方法需要使用者輸入四個引數
what:表示設定的格式是什麼,可以是前景色、背景色也可以是可點選的文字等等
start:表示需要設定格式的字元的起始下標
end:表示需要設定格式的字元的結尾下標
flags:屬性就有意思了,共有四種屬性分別是:

Spanned.SPAN_INCLUSIVE_EXCLUSIVE 從起始下標到終了下標,包括起始下標
Spanned.SPAN_INCLUSIVE_INCLUSIVE 從起始下標到終了下標,同時包括起始下標和終了下標
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 從起始下標到終了下標,但都不包括起始下標和終了下標
Spanned.SPAN_EXCLUSIVE_INCLUSIVE 從起始下標到終了下標,包括終了下標



下面我們一一解讀幾種Span常用的格式:




ForegroundColorSpan:

為文字設定前景色,效果和TextView的setTextColor()類似,實現方法如下:

效果:

這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("設定文字的前景色為淡藍色");
ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#0099EE"));
spannableString.setSpan(colorSpan, 9, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); 
textView.setText(spannableString);




BackgroundColorSpan:

為文字設定背景色,效果和TextView的setBackground()類,實現方法如下:

效果:
這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("設定文字的背景色為淡綠色");
BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
spannableString.setSpan(colorSpan, 9, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);




RelativeSizeSpan:

設定文字相對大小,在TextView原有的文字大小的基礎上,相對設定文字大小,實現方法如下:

效果:
這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("萬丈高樓平地起");

RelativeSizeSpan sizeSpan01 = new RelativeSizeSpan(1.2f);
RelativeSizeSpan sizeSpan02 = new RelativeSizeSpan(1.4f);
RelativeSizeSpan sizeSpan03 = new RelativeSizeSpan(1.6f);
RelativeSizeSpan sizeSpan04 = new RelativeSizeSpan(1.8f);
RelativeSizeSpan sizeSpan05 = new RelativeSizeSpan(1.6f);
RelativeSizeSpan sizeSpan06 = new RelativeSizeSpan(1.4f);
RelativeSizeSpan sizeSpan07 = new RelativeSizeSpan(1.2f);

spannableString.setSpan(sizeSpan01, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan02, 1, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan03, 2, 3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan04, 3, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan05, 4, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan06, 5, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan07, 6, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);





StrikethroughSpan:

為文字設定中劃線,也就是常說的刪除線,實現方法如下:

效果:
這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("為文字設定刪除線");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);





UnderlineSpan:

為文字設定下劃線,具體實現方法如下:

效果:

這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("為文字設定下劃線");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString); 




SuperscriptSpan:

設定上標,具體實現方法如下:


效果:

這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("為文字設定上標");
SuperscriptSpan superscriptSpan = new SuperscriptSpan();
spannableString.setSpan(superscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);




SubscriptSpan:

設定下標,功能與設定上標類似,不做過多描述,具體實現方法如下:

效果:


這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("為文字設定下標");
SubscriptSpan subscriptSpan = new SubscriptSpan();
spannableString.setSpan(subscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);




StyleSpan:

為文字設定風格(粗體、斜體),和TextView屬性textStyle類似,實現方法如下:


效果:

這裡寫圖片描述

程式碼:

SpannableString spannableString = new SpannableString("為文字設定粗體、斜體風格");
StyleSpan styleSpan_B  = new StyleSpan(Typeface.BOLD);
StyleSpan styleSpan_I  = new StyleSpan(Typeface.ITALIC);
spannableString.setSpan(styleSpan_B, 5, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(styleSpan_I, 8, 10, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setHighlightColor(Color.parseColor("#36969696"));
textView.setText(spannableString);




ImageSpan:

設定文字圖片,實現方法如下:


效果:

這裡寫圖片描述


程式碼:

SpannableString spannableString = new SpannableString("在文字中新增表情(表情)");
Drawable drawable = getResources().getDrawable(R.mipmap.a9c);
drawable.setBounds(0, 0, 42, 42);
ImageSpan imageSpan = new ImageSpan(drawable);
spannableString.setSpan(imageSpan, 6, 8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);




ClickableSpan:

設定可點選的文字,設定這個屬性的文字可以相應使用者點選事件,至於點選事件使用者可以自定義,就像效果圖顯示一樣,使用者可以實現點選跳轉頁面的效果,具體實現方法如下:


效果:

這裡寫圖片描述


程式碼:

SpannableString spannableString = new SpannableString("為文字設定點選事件");
MyClickableSpan clickableSpan = new MyClickableSpan("http://www.jianshu.com/users/dbae9ac95c78");
spannableString.setSpan(clickableSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.parseColor("#36969696")); 
textView.setText(spannableString);

/***************************************************************/

class MyClickableSpan extends ClickableSpan {

    private String content;

    public MyClickableSpan(String content) {
        this.content = content;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
    }

    @Override
    public void onClick(View widget) {
        //TODO 在這裡寫點選事件!!!!!
    }
}

注意:使用ClickableSpan的文字如果想真正實現點選作用,必須為TextView設定setMovementMethod方法,否則沒有點選相應,至於setHighlightColor方法則是控制點選時的背景色。




URLSpan:

設定超連結文字,其實聰明的小夥幫在講到ClickableSpan的時候就能實現超連結文字的效果了,重寫onClick點選事件就行,也確實看了URLSpan的原始碼,URLSpan就是繼承自ClickableSpan,也和想象中一樣,就是重寫了父類的onClick事件,用系統自帶瀏覽器開啟連結,具體實現方法如下:



效果:

這裡寫圖片描述


程式碼:

SpannableString spannableString = new SpannableString("為文字設定超連結");
MyURLSpan urlSpan= new MyURLSpan ("http://blog.csdn.net/fan7983377");
spannableString.setSpan(urlSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.parseColor("#FF0000")); 
textView.setText(spannableString);


class MyURLSpan extends URLSpan{

        public MyURLSpan(String url) {
            super(url);
        }

        public void onClick(View widget) {
            Uri uri = Uri.parse(getURL());
            Context context = widget.getContext();
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
            try {
                context.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                Log.w("URLSpan", "Actvity was not found for intent, " + intent.toString());
            }
        }

    }

注意:使用URLSpan的文字如果想真正實現點選作用,必須為TextView設定setMovementMethod方法,否則沒有點選相應,至於setHighlightColor方法則是控制點選時的背景色。



除此之外,還有MaskFilterSpan可以實現模糊和浮雕效果,RasterizerSpan可以實現光柵效果,因為以上兩個使用頻率不高,而且效果也不是很明顯,就不做詳細說明,有興趣的小夥伴不妨去試一試。

下面的動畫實現起來是不是很輕鬆啦?不會的可以參考附件的程式碼

這裡寫圖片描述

原始碼下載:點選下載

相關文章