安卓文本樣式-Spannable的使用

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0120/2335.html

 

編輯推薦:稀土掘金,這是一個針對技術開發者的一個應用,你可以在掘金上獲取最新最優質的技術乾貨,不僅僅是Android知識、前端、後端以至於產品和設計都有涉獵,想成爲全棧工程師的朋友不要錯過!

本文轉載自 lixin84915的博客 Android文本樣式  原文分爲上下兩部分,本文將上下整理成了一篇文章。


在android中,有 時候需要對文本進行各種特別的設置,比如顏色、大小、首行縮進,或者是在一段文本中加入圖片,甚至是書寫一些特殊的公式。如果通過佈局文件使用多個控件來 實現,一方面會使的使用起來特別的複雜,增加了佈局文件維護的難度,另一方面,如果加入了太多的控件,在頁面加載時也要耗費更多的資源。如果在HTML 中,則可以使用各種標籤來實現這些特殊效果,而在android中有類似的機制,只不過不是使用標籤來實現,而是使用Spannable對象來實現。

一、關於Spannable的構建:

可以看出,Spannable繼承自Spanned接口,而實際上,Spanned繼承自CharSequence接口:

在TextView的 setText(CharSequence text)方法中,要求的參數正好是一個CharSequence對象,因此,我們可以通過Spannable對象來直接使用setText來完成文本的 設置。在使用中通常使用Spannable spn = new SpannableString("字符串");或者通過SpannableStringBuilder對象來進行構建。

二、給Spannable對象設置樣式:

在構建除了Spannable 對象以後,就可以使用spannable.setSpan(Obj what, int start, int end, int flags)方法來進行樣式的設置了,其中參數what是具體樣式的實現對象,start則是該樣式開始的位置,end對應的是樣式結束的位置,參數 flags,定義在Spannable中的常量,常用的有:

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含兩端start和end所在的端點              (a,b)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端點       (a,b]
Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含兩端start,但不包含end所在的端點   [a,b)
Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含兩端start和end所在的端點                     [a,b]

但實際測試這其中似乎並未有差別,而在start和end相同的情況下,則只對start所在字符的當前行起作用。

三、樣式分析:

用來構建樣式的具體的類都在android.text.style包下,下面逐一進行分析。

1.AbsoluteSizeSpan

顧名思義,AbsoluteSizeSpan是指絕對尺寸,通過指定絕對尺寸來改變文本的字體大小。該類有三個構造函數:
AbsoluteSizeSpan(int size)、AbsoluteSizeSpan(int size, boolean dip)、AbsoluteSizeSpan(Parcel src)。
AbsoluteSizeSpan(int size):參數size, 以size的指定的像素值來設定文本大小。
AbsoluteSizeSpan(int size, boolean dip):參數size,以size的指定像素值來設定文本大小,如果參數dip爲true則以size指定的dip爲值來設定文本大小。
AbsoluteSizeSpan(Parcel src):參數src,包含有size和dip值的包裝類。在該構造中
public AbsoluteSizeSpan(Parcel src) {
mSize = src.readInt();
mDip = src.readInt() != 0;    
}
使用範例:
Parcel p = Parcel.obtain();
p.writeInt(29);//字體大小
p.writeInt(8);//是否是dip單位
p.setDataPosition(0);
AbsoluteSizeSpan ass = new AbsoluteSizeSpan(p);
效果:

2.AlignmentSpan.Standard

AlignmentSpan.Standard, 標準文本對齊樣式,該類有兩個構造函數,AlignmentSpan.Standard(Layout.Alignment align)和AlignmentSpan.Standard(Parcel src)。AlignmentSpan.Standard(Layout.Alignment align):參數align,Layout.Alignment類型的枚舉值。包括居中、正常和相反三種情況。
AlignmentSpan.Standard(Parcel src):參數src,包含有標準字符串的Parcel類,其值應爲"ALIGN_CENTER"、"ALIGN_NORMAL" 或"ALIGN_OPPOSITE"中的之一,對應Layout.Alignment枚舉中的三個類型。使用示例:
Parcel p = Parcel.obtain();
p.writeString(\"ALIGN_CENTER\");
p.setDataPosition(0);
AlignmentSpan.Standard standard = new AlignmentSpan.Standard(p);
效果:

3.BackgroundColorSpan

BackgroundColorSpan,背景色樣式,顯然可以用來設定文本的背景色。該類有兩個構造函數,BackgroundColorSpan(int color)和BackgroundColorSpan(Parcel src)。
BackgroundColorSpan(int color):參數color,顏色值。
BackgroundColorSpan(Parcel src):參數src,包含顏色值信息的包裝類,使用方法如下:
Parcel p = Parcel.obtain();
p.writeInt(Color.GREEN);
p.setDataPosition(0);
BackgroundColorSpan bcs = new BackgroundColorSpan(p);
效果:

4.BulletSpan

BulletSpan, 着重樣式,類似於HTML中的<li>標籤的圓點效果。該類有4個構造函數BulletSpan()、BulletSpan(int gapWidth)、BulletSpan(int gapWidth,int color)、BulletSpan(Parcel src)。
BulletSpan():僅提供一個與文本顏色一致的符號。
BulletSpan(int gapWidth): 提供一個與文本顏色一致的符號,並指定符號與後面文字之間的空白長度。
BulletSpan(int gapWidth,int color):提供一個指定顏色的符號,並指定符號與後面文字之間的寬度。
BulletSpan(Parcel src):參數src,包含寬度、顏色信息的包裝類,在以此構造時,構造函數的調用如下:
mGapWidth = src.readInt();
mWantColor = src.readInt() != 0;\nmColor = src.readInt();
如果使用Parcel作爲參數時,使用方式爲:
Parcel p = Parcel.obtain();
p.writeInt(20);//設置gapWidth
p.writeInt(1);//設置是否使用顏色
p.writeInt(Color.YELLOW);//設置顏色
p.setDataPosition(0);
BulletSpan bs3 = new BulletSpan(p);
效果:

5.DrawableMarginSpan

DrawableMarginSpan,圖片+Margin樣式,該類有兩個構造函數:DrawableMarginSpan(Drawable b)、DrawableMarginSpan(Drawable b,int pad)。
DrawableMarginSpan(Drawable b):參數b,用於顯示的圖片。
DrawableMarginSpan(Drawable b,int pad):參數b,用於顯示的圖片,參數pad,圖片和文字的距離。
效果:

6.ForegroundColorSpan

ForegroundColorSpan,字體顏色樣式,用於改變字體顏色。該類有兩個構造函數:ForegroundColorSpan(int color)、ForegroundColorSpan(Parcel src)。
ForegroundColorSpan(int color):參數color,字體顏色。
ForegroundColorSpan(Parcel src):參數src,包含字體顏色信息的包裝類,使用如下:
Parcel p = Parcel.obtain();
p.writeInt(Color.YELLOW);
p.setDataPosition(0);
ForegroundColorSpan fcs = new ForegroundColorSpan(p);
效果:

7.IconMarginSpan

IconMarginSpan,圖標+Margin樣式,該類與DrawableMarginSpan使用上很相似。本類有兩個構造函數:
IconMarginSpan(Bitmap b):參數b,用於顯示圖像的bitmap。
IconMarginSpan(Bitmap b,int pad):參數b,用於顯示圖像的bitmap,參數pad,Bitmap和文本之間的間距。
效果:

8.ImageSpan

ImageSpan,圖片樣式,主要用於在文本中插入圖片。本類構造函數較多,但主要是針對Bitmap和Drawable的,也可以通過資源Id直接加載圖片。如下:
ImageSpan(Bitmap b):.參數b,用於顯示的Bitmap。該方法已過時,改用Use ImageSpan(Context, Bitmap)代替。
ImageSpan(Bitmap b, int verticalAlignment):參數b,用於顯示的Bitmap,參數verticalAlignment,對齊方式,對應ImageSpan中 的常量值。該方法已過時,改用ImageSpan(Context, Bitmap, int)代替。
ImageSpan(Context context, Bitmap b):參數context,傳入的上下文,參數b,用於顯示的Bitmap。
ImageSpan(Context context, Bitmap b, int verticalAlignment):參數context,傳入的上下文,參數b,用於顯示的Bitmap,參數verticalAlignment,對齊方式。
ImageSpan(Drawable d):參數d,用於顯示的Drawable,此Drawable須設置大小。
ImageSpan(Drawable d, int verticalAlignment):參數d,用於顯示的Drawable,參數verticalAlignment,對齊方式。
ImageSpan(Drawable d, String source):參數d,用於顯示的Drawable,參數source,資源字符串。
ImageSpan(Drawable d, String source, int verticalAlignment):參數d,用於顯示的Drawable,參數source,資源字符串,參數verticalAlignment,對齊方式。
ImageSpan(Context context, Uri uri):參數context,傳入的上下文,參數uri,圖片的uri。
ImageSpan(Context context, Uri uri, int verticalAlignment):參數context,傳入的上下文,參數uri,圖片的uri,參數verticalAlignment,對齊方式。
ImageSpan(Context context, int resourceId):參數context,傳入的上下文,參數resourceId,圖片的資源id。
ImageSpan(Context context, int resourceId, int verticalAlignment)參數context,傳入的上下文,參數resourceId,圖片的資源id,參數verticalAlignment,對齊方式。
效果:

9.LeadingMarginSpan

LeadingMarginSpan.Standard,文本縮進的樣式。有3個構造函數,分別爲:
Standard(int arg0):參數arg0,縮進的像素。
Standard(int arg0, int arg1):參數arg0,首行縮進的像素,arg1,剩餘行縮進的像素。
Standard(Parcel p): 參數p,包含縮進信息的包裝類。在構造時,
public Standard(Parcel src) {
    mFirst = src.readInt();\n"+
    mRest = src.readInt();\n"+
}
使用方式:
Parcel p = Parcel.obtain();
p.writeInt(20);
p.writeInt(30);
p.setDataPosition(0);
Standard lms = new Standard(p);
效果:

10.MaskFilterSpan

MaskFilterSpan,濾鏡樣式,只有一個構造函數:
MaskFilterSpan(MaskFilter filter):參數filter,濾鏡樣式。
說明:
在android系統裏,MaskFilter提供了兩個子類,BlurMaskFilter和EmbossMaskFilter,分別用來製作模糊效果和浮雕效果。
效果:

11.QuoteSpan

QuoteSpan,引用樣式,在文本左側添加一條表示引用的豎線,該類有3個構造函數:
QuoteSpan():無參構造,默認顏色爲藍色。
QuoteSpan(int color):參數color,顏色值。
QuoteSpan(Parcel src):包含顏色值信息的包裝類。使用:
Parcel p = Parcel.obtain();
p.writeInt(Color.BLACK);
p.setDataPosition(0);
QuoteSpan qs = new QuoteSpan(p);
效果:

12.RasterizerSpan

RasterizerSpan,字面義爲光柵化,實際效果不明顯,待完善。一個構造函數:
RasterizerSpan(Rasterizer r):Rasterizer只有一個系統定義了的子類LayerRasterizer

13.RelativeSizeSpan

RelativeSizeSpan,相對大小,指相對於文本設定的大小的相對比例,如果沒有設定則採用系統默認值。該類有兩個構造函數:
RelativeSizeSpan(float proportion):參數proportion,比例值。如果文字設定大小爲A,則顯示出來的大小爲A×proportion。
RelativeSizeSpan(Parcel src):參數src,包含了比例值信息的包裝類。使用:
Parcel p = Parcel.obtain();
p.writeFloat(2.5f);
p.setDataPosition(0);
RelativeSizeSpan rss = new RelativeSizeSpan(p);
效果:

14.ScaleXSpan

ScaleXSpan,橫向縮放樣式,將字體按比例進行橫向縮放。構造函數:
ScaleXSpan(float proportion):參數proportion,縮放比例。如果字體設置的大小爲A,則實際顯示爲A×proportion。
ScaleXSpan(Parcel src):參數src,包含了縮放比例信息的包裝類。使用:
Parcel p = Parcel.obtain();
p.writeFloat(2.5f);
p.setDataPosition(0);
ScaleXSpan rss = new ScaleXSpan(p);
效果:

15.StrikethroughSpan

StrikethroughSpan,刪除線樣式。該類有兩個構造函數:
StrikethroughSpan()和SrickkethroughSapn(Parcel src)。但有參數的構造函數並未對src參數做處理,
public StrikethroughSpan(Parcel src) {
}
因此這兩個構造函數完全是同樣的效果。

16.StyleSpan

StyleSpan,主要由正常、粗體、斜體和同時加粗傾斜四種樣式,常量值定義在Typeface類中。構造函數:
StyleSpan(int style):參數style,定義在Typeface中的常量。
StyleSpan(Parcel src):參數src,包含字體信息的包裝類,用法:
Parcel p = Parcel.obtain();
p.writeInt(Typeface.BOLD_ITALIC);
p.setDataPosition(0);
StyleSpan ss = new StyleSpan(p);
效果:

17.SubscriptSpan

SubscriptSpan,腳註樣式,比如化學式的常見寫法,當然,還可以對腳註的文字做一定的縮放。構造函數:
SubscriptSpan():無參構造。
SubscriptSpan(Parcel src):一參構造,參數src並未起任何作用,源碼中爲:
public SuperscriptSpan(Parcel src) {
}
效果:

18.SuperscriptSpan

SuperscriptSpan,上標樣式,比如數學上的次方運算,當然,還可以對上標文字進行縮放。構造函數:
SuperscriptSpan():無參構造。
SuperscriptSpan(Parcel src):一參構造,參數src並未起任何作用,源碼中爲:
public SuperscriptSpan(Parcel src) {
}
效果:

19.TabStopSpan

TabStopSpan.Standard,製表位偏移樣式,距離每行的leading margin的偏移量,據測試在首行加入製表符時才產生效果。構造函數:
TabStopSpan.Standard(int where):參數where,偏移量。
效果:

20.TextAppearanceSpan

TextAppearanceSpan,使用style文件來定義文本樣式,該類有4個構造函數:
TextAppearanceSpan(Context context, int appearance):參數context,傳入的上下文,參數appearance,引用的樣式表,如R.style.my_style。
TextAppearanceSpan(Context context, int appearance, int colorList):參數context,使用的上下文,參數appearance,引用的樣式表,如R.style.my_style,參數 colorList,使用方式未知,如果設置爲小於0,則參數將不產生效果。
TextAppearanceSpan(String family, int style, int size,ColorStateList color, ColorStateList linkColor):參數family,字體,僅支持系統自帶的三種字體,MONOSPACE、SERIF和SANS,參數 style,TypeFace中定義的字體樣式,BOLD、ITALIC等,參數size,字體大小,參數color,字體顏色,參數 linkColor,使用方式未知。TextAppearanceSpan(Parcel src):參數src,含有樣式信息的包裝類,樣式信息參照5參構造。使用:
Parcel p = Parcel.obtain();
p.writeString(\"SERIF\");
p.writeInt(Typeface.BOLD_ITALIC);
p.writeInt(10);
try {
    ColorStateList colorlist = ColorStateList.createFromXml(ctx.getResources(),ctx.getResources().getXml(R.drawable.parcelcolorlist));
    p.writeInt(1);
    colorlist.writeToParcel(p, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    p.writeInt(1);
    colorlist.writeToParcel(p, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} catch (Exception e) {
    e.printStackTrace();
}
p.setDataPosition(0);
TextAppearanceSpan tas = new TextAppearanceSpan(p);
注:在這個設置中style似乎並未起到作用,另外關於這個類的colorList和linkColor參數的使用尚不明瞭,有待解答。
效果:

21.TypefaceSpan

TypefaceSpan,字體樣式,可以設置不同的字體,比如系統自帶的SANS_SERIF、MONOSPACE和SERIF。構造函數:
TypefaceSpan(String family):參數family,字體的值,以字符串表示。
TypefaceSpan(Parcel src): 參數src,包含字體family信息的包裝類,使用如下:
Parcel p = Parcel.obtain();
p.writeString(\"SERIF\");
p.setDataPosition(0);
TypefaceSpan ts = new TypefaceSpan(p);
 效果:

22.UnderlineSpan

UnderlineSpan,下劃線樣式,給一段文字加上下劃線。構造函數:
UnderlineSpan(): 無參構造。
UnderlineSpan(Parcel src):一參構造, 與無參構造效果相同,構造中未對src做處理。源碼:
public UnderlineSpan(Parcel src) {
}
效果:

23.URLSpan

URLSpan,可以打開一個鏈接。兩個構造函數:
URLSpan(String url):參數url,鏈接地址。
URLSpan(Parcel src):參數src,包含鏈接地址信息的包裝類,使用如下:
Parcel p = Parcel.obtain();
p.writeString("http://www.sina.com.cn");
p.setDataPosition(0);
URLSpan us = new URLSpan(p);
效果:

四、標註:

以上效果均在android2.3中測試,以後新增的幾個類並未做說明,上面的類中還有幾處使用的不甚明瞭的地方,希望能夠儘快的完善。
以上所有的效果均寫在了一個APK裏,源碼已上傳至Android文本樣式

 

 

發佈了104 篇原創文章 · 獲贊 152 · 訪問量 101萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章