Android中的SpannableString與SpannableStringBuilder詳解
前言
最近在學(xué)習(xí)Android開(kāi)發(fā),發(fā)現(xiàn)確實(shí)有太多東西需要去整理,去學(xué)習(xí)。慢慢來(lái)吧,任何東東的深入學(xué)習(xí)都是不簡(jiǎn)單的。今天稍微整理下SpannableString與SpannableStringBuilder,因?yàn)樵谏掀?,我們?cè)v到過(guò)有關(guān)CharSequence的東東,有關(guān)CharSequence的話,這兩個(gè)類是必談的,所以這里加以整理。
一、概述
1、SpannableString、SpannableStringBuilder與String的關(guān)系
首先SpannableString、SpannableStringBuilder基本上與String差不多,也是用來(lái)存儲(chǔ)字符串,但它們倆的特殊就在于有一個(gè)SetSpan()
函數(shù),能給這些存儲(chǔ)的String添加各種格式或者稱樣式(Span),將原來(lái)的String以不同的樣式顯示出來(lái),比如在原來(lái)String上加下劃線、加背景色、改變字體顏色、用圖片把指定的文字給替換掉,等等。所以,總而言之,SpannableString、SpannableStringBuilder與String一樣, 首先也是傳字符串,但SpannableString、SpannableStringBuilder可以對(duì)這些字符串添加額外的樣式信息,但String則不行。
注意:如果這些額外信息能被所用的方式支持,比如將SpannableString傳給TextView;也有對(duì)這些額外信息不支持的,比如前一章講到的Canvas繪制文字,對(duì)于不支持的情況,SpannableString和SpannableStringBuilder就是退化為String類型,直接顯示原來(lái)的String字符串,而不會(huì)再顯示這些附加的額外信息。
2、SpannableString與SpannableStringBuilder區(qū)別
它們的區(qū)別在于 SpannableString像一個(gè)String一樣,構(gòu)造對(duì)象的時(shí)候傳入一個(gè)String,之后再無(wú)法更改String的內(nèi)容,也無(wú)法拼接多個(gè) SpannableString;而SpannableStringBuilder則更像是StringBuilder,它可以通過(guò)其append()
方法來(lái)拼接多個(gè)String:
//使用SpannableString,必須一次傳入,構(gòu)造完成 SpannableString word = new SpannableString("歡迎光臨Harvic的博客"); //使用SpannableStringBuilder,可以使用append()再添加 SpannableStringBuilder multiWord = new SpannableStringBuilder(); multiWord.append("歡迎光臨"); multiWord.append("Harvic的"); multiWord.append("博客");
(轉(zhuǎn)自博客:《android - SpannableString或SpannableStringBuilder以及string.xml文件中的整型和string型代替》)
因?yàn)镾pannable等最終都實(shí)現(xiàn)了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通過(guò)TextView.setText()
設(shè)置給TextView。
3、SetSpan()
void setSpan (Object what, int start, int end, int flags)
函數(shù)意義:給SpannableString或SpannableStringBuilder特定范圍的字符串設(shè)定Span樣式,可以設(shè)置多個(gè)(比如同時(shí)加上下劃線和刪除線等),F(xiàn)alg參數(shù)標(biāo)識(shí)了當(dāng)在所標(biāo)記范圍前和標(biāo)記范圍后緊貼著插入新字符時(shí)的動(dòng)作,即是否對(duì)新插入的字符應(yīng)用同樣的樣式。(這個(gè)后面會(huì)具體舉例說(shuō)明)
參數(shù)說(shuō)明:
- object what :對(duì)應(yīng)的各種Span,后面會(huì)提到;
- int start:開(kāi)始應(yīng)用指定Span的位置,索引從0開(kāi)始
- int end:結(jié)束應(yīng)用指定Span的位置,特效并不包括這個(gè)位置。比如如果這里數(shù)為3(即第4個(gè)字符),第4個(gè)字符不會(huì)有任何特效。從下面的例子也可以看出來(lái)。
int flags:取值有如下四個(gè)
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范圍的前面和后面插入新字符都不會(huì)應(yīng)用新樣式
- Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即僅在范圍字符的后面插入新字符時(shí)會(huì)應(yīng)用新樣式
- Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。
- Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。
舉個(gè)例子來(lái)說(shuō)明這個(gè)前后包括的問(wèn)題:
由于Flag的作用是用來(lái)指定范圍前后輸入新的字符時(shí),會(huì)不會(huì)應(yīng)用效果的,所以我們利用EditText來(lái)顯示SpannableString
(1)、布局XML中加入一個(gè)EditText控件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 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" > <EditText android:id="@+id/edit" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
(2)、這里用一個(gè)改變字體顏色的Span來(lái)做下演示
public class MainActivity extends Activity { private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText)findViewById(R.id.edit); //改變字體顏色 //先構(gòu)造SpannableString SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); //再構(gòu)造一個(gè)改變字體顏色的Span ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE); //將這個(gè)Span應(yīng)用于指定范圍的字體 spanString.setSpan(span, 1, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //設(shè)置給EditText顯示出來(lái) editText.setText(spanString); } }
初始化效果是這樣的:
分別在設(shè)置Span的前面和后面加入新文字,結(jié)果是這樣的
在前面和后面都加入蝦米兩個(gè)字,可見(jiàn),前面的蝦米沒(méi)有任何效果,后面的則不同,添加上相同的Span特效,這是由于我們?cè)O(shè)置了Spannable.SPAN_EXCLUSIVE_INCLUSIVE的原因,即(前面不應(yīng)用特效,后面應(yīng)用特效),其它幾個(gè)Flags參數(shù)的含義想必大家也都清楚了。在此就不再贅述。
二、各種Span設(shè)置
在前面的一個(gè)小示例,大家應(yīng)該也可以看出,要應(yīng)用一個(gè)Span總共分三步:
1、構(gòu)造String
2、構(gòu)造Span
3、利用SetSpan()對(duì)指定范圍的String應(yīng)用這個(gè)Span
1、字體顏色設(shè)置(ForegroundColorSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); //再構(gòu)造一個(gè)改變字體顏色的Span ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE); //將這個(gè)Span應(yīng)用于指定范圍的字體 spanString.setSpan(span, 1, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //設(shè)置給EditText顯示出來(lái) editText.setText(spanString);
效果:
2、字體背景顏色(BackgroundColorSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW); spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
3、字體大?。ˋbsoluteSizeSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); AbsoluteSizeSpan span = new AbsoluteSizeSpan(16); spanString.setSpan(span, 2, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE); editText.setText(spanString);
4、粗體、斜體(StyleSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC); spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
5、刪除線(StrikethroughSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); StrikethroughSpan span = new StrikethroughSpan(); spanString.setSpan(span, 2, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
6、下劃線(UnderlineSpan)
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); UnderlineSpan span = new UnderlineSpan(); spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
7、圖片置換(ImageSpan)
ImagSpan有很多構(gòu)造函數(shù),一般是通過(guò)傳入Drawableg來(lái)構(gòu)造,詳細(xì)的構(gòu)造說(shuō)明看這里:http://developer.android.com/reference/android/text/style/ImageSpan.html
SpannableString spanString = new SpannableString("歡迎光臨Harvic的博客"); Drawable d = getResources().getDrawable(R.drawable.ic_launcher); d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); spanString.setSpan(span, 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
這個(gè)函數(shù)的不同之處在于,前幾都是在原來(lái)文字的基礎(chǔ)上加上特效,而這里卻是利用圖片將文字替換。如果遇到不支持顯示圖片的函數(shù),比如前一篇中的canvas繪圖。就會(huì)退化成String,即以原來(lái)的String字符串來(lái)顯示。
本篇文章所涉及到圖片及工程下載地址:http://xiazai.jb51.net/201710/yuanma/SpannableString_SpannableStringBuilder(jb51.net).rar
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android實(shí)現(xiàn)調(diào)用手機(jī)攝像頭錄像限制錄像時(shí)長(zhǎng)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)調(diào)用手機(jī)攝像頭錄像限制錄像時(shí)長(zhǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Android網(wǎng)絡(luò)通信基礎(chǔ)類源碼分析講解
這篇文章主要介紹了Android網(wǎng)絡(luò)通信基礎(chǔ)類源碼,包括了Handler、Looper、Thread的分析講解,對(duì)日常開(kāi)發(fā)學(xué)習(xí)很有幫助,需要的朋友可以參考下2024-05-05Filter過(guò)濾器和Listener監(jiān)聽(tīng)器詳解
這篇文章主要介紹了 Filter過(guò)濾器和Listener監(jiān)聽(tīng)器詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04android加載系統(tǒng)相冊(cè)圖片并顯示詳解
大家好,本篇文章主要講的是android加載系統(tǒng)相冊(cè)圖片并顯示詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12Android進(jìn)階篇-自定義圖片伸縮控件具體實(shí)例
這篇文章介紹了Android自定義圖片伸縮控件具體實(shí)例,有需要的朋友可以參考一下2013-11-11Android studio button 按鈕 四種綁定事件的方法【實(shí)例代碼】
這篇文章主要介紹了Android studio button 按鈕 四種綁定事件的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08Android 改變圖標(biāo)原有顏色和搜索框的實(shí)例代碼
讓Android也能有iOS那么方便的圖片色調(diào)轉(zhuǎn)換,就像同一個(gè)圖標(biāo),但是有多個(gè)地方使用,并且顏色不一樣,就可以用這個(gè)方法了。 本文實(shí)現(xiàn)TextView圖片和文字居中,鍵盤搜索功能,具體實(shí)現(xiàn)代碼大家跟隨腳本之家小編看看吧2017-09-09Android通過(guò)JNI實(shí)現(xiàn)守護(hù)進(jìn)程
這篇文章主要為大家詳細(xì)介紹了Android通過(guò)JNI實(shí)現(xiàn)守護(hù)進(jìn)程的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-09-09