SpannableString與SpannableStringBuilder

一、概述

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:

[java]view plaincopy

//使用SpannableString,必須一次傳入,構(gòu)造完成

SpannableString?word?=newSpannableString("歡迎光臨Harvic的博客");

//使用SpannableStringBuilder,可以使用append()再添加

SpannableStringBuilder?multiWord?=newSpannableStringBuilder();

multiWord.append("歡迎光臨");

multiWord.append("Harvic的");

multiWord.append("博客");

(轉(zhuǎn)自博客:《android - SpannableString或SpannableStringBuilder以及string.xml文件中的整型和string型代替》

因為Spannable等最終都實現(xiàn)了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通過TextView.setText()設(shè)置給TextView。

3、SetSpan()

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

函數(shù)意義:給SpannableString或SpannableStringBuilder特定范圍的字符串設(shè)定Span樣式,可以設(shè)置多個(比如同時加上下劃線和刪除線等),F(xiàn)alg參數(shù)標識了當在所標記范圍前和標記范圍后緊貼著插入新字符時的動作,即是否對新插入的字符應用同樣的樣式。(這個后面會具體舉例說明)

參數(shù)說明:

object what :對應的各種Span,后面會提到;

int start:開始應用指定Span的位置,索引從0開始

int end:結(jié)束應用指定Span的位置,特效并不包括這個位置。比如如果這里數(shù)為3(即第4個字符),第4個字符不會有任何特效。從下面的例子也可以看出來。

int flags:取值有如下四個

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范圍的前面和后面插入新字符都不會應用新樣式Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即僅在范圍字符的后面插入新字符時會應用新樣式

Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。

Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。

舉個例子來說明這個前后包括的問題:

由于Flag的作用是用來指定范圍前后輸入新的字符時,會不會應用效果的,所以我們利用EditText來顯示SpannableString

(1)、布局XML中加入一個EditText控件:

[html]view plaincopy

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.example.try_spannable_blog.MainActivity">

android:id="@+id/edit"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

(2)、這里用一個改變字體顏色的Span來做下演示

[java]view plaincopy

publicclassMainActivityextendsActivity?{

privateEditText?editText;

@Override

protectedvoidonCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

editText?=?(EditText)findViewById(R.id.edit);

//改變字體顏色

//先構(gòu)造SpannableString

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

//再構(gòu)造一個改變字體顏色的Span

ForegroundColorSpan?span?=newForegroundColorSpan(Color.BLUE);

//將這個Span應用于指定范圍的字體

spanString.setSpan(span,1,3,?Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

//設(shè)置給EditText顯示出來

editText.setText(spanString);

}

}

初始化效果是這樣的:

分別在設(shè)置Span的前面和后面加入新文字,結(jié)果是這樣的

在前面和后面都加入蝦米兩個字,可見,前面的蝦米沒有任何效果,后面的則不同,添加上相同的Span特效,這是由于我們設(shè)置了Spannable.SPAN_EXCLUSIVE_INCLUSIVE的原因,即(前面不應用特效,后面應用特效),其它幾個Flags參數(shù)的含義想必大家也都清楚了。在此就不再贅述。

二、各種Span設(shè)置

在前面的一個小示例,大家應該也可以看出,要應用一個Span總共分三步:

1、構(gòu)造String

2、構(gòu)造Span

3、利用SetSpan()對指定范圍的String應用這個Span

1、字體顏色設(shè)置(ForegroundColorSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

//再構(gòu)造一個改變字體顏色的Span

ForegroundColorSpan?span?=newForegroundColorSpan(Color.BLUE);

//將這個Span應用于指定范圍的字體

spanString.setSpan(span,1,5,?Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

//設(shè)置給EditText顯示出來

editText.setText(spanString);

效果:

2、字體背景顏色(BackgroundColorSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

BackgroundColorSpan?span?=newBackgroundColorSpan(Color.YELLOW);

spanString.setSpan(span,0,3,?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setText(spanString);

3、字體大?。ˋbsoluteSizeSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

AbsoluteSizeSpan?span?=newAbsoluteSizeSpan(16);

spanString.setSpan(span,2,5,?Spannable.SPAN_INCLUSIVE_INCLUSIVE);

editText.setText(spanString);

4、粗體、斜體(StyleSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

StyleSpan?span?=newStyleSpan(Typeface.BOLD_ITALIC);

spanString.setSpan(span,1,4,?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setText(spanString);

5、刪除線(StrikethroughSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

StrikethroughSpan?span?=newStrikethroughSpan();

spanString.setSpan(span,2,5,?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setText(spanString);

6、下劃線(UnderlineSpan)

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

UnderlineSpan?span?=newUnderlineSpan();

spanString.setSpan(span,1,4,?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setText(spanString);

7、圖片置換(ImageSpan)

ImagSpan有很多構(gòu)造函數(shù),一般是通過傳入Drawableg來構(gòu)造,詳細的構(gòu)造說明看這里:http://developer.android.com/reference/android/text/style/ImageSpan.html

[java]view plaincopy

SpannableString?spanString?=newSpannableString("歡迎光臨Harvic的博客");

Drawable?d?=?getResources().getDrawable(R.drawable.ic_launcher);

d.setBounds(0,0,?d.getIntrinsicWidth(),?d.getIntrinsicHeight());

ImageSpan?span?=newImageSpan(d,?ImageSpan.ALIGN_BASELINE);

spanString.setSpan(span,2,4,?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setText(spanString);

這個函數(shù)的不同之處在于,前幾都是在原來文字的基礎(chǔ)上加上特效,而這里卻是利用圖片將文字替換。如果遇到不支持顯示圖片的函數(shù),比如前一篇中的canvas繪圖。就會退化成String,即以原來的String字符串來顯示。

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

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

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