Span 介紹及使用(二)
上一節介紹了一下Span
,有些亂,這一節我們來講講Android 提供的各種Span
的應用。
使用 Span
的步驟
- 定義你要顯示的文字
- 定義你需要的
Span
- 使用將要顯示文字,構造一個
SpannableString
- 呼叫
SpannableString
的setSpan()
方法設定span
;setSpan()
的引數會有設定文字的範圍。 - 呼叫
TextView
的setText()
方法,顯示SpannableString
修改字元文字格式時使用的CharacterStyle
當我們遇到在佈局裡無法處理的文字格式,我們就可以使用CharacterStyle
。
ClickableSpan:可設定文字區域性點選,區域性文字的顏色
ClickableSpan
同時繼承了CharacterStyle
和實現了UpdateAppearance
這個Span
是第一節開頭提到的問題的最好解決方式。
按照上面的步驟我們來使用 ClickableSpan
實現區域性點選,並且使點選的文字變色
//1.定義需要顯示的文字;使“《協議》”變色,並且給“《協議》”新增點選事件, final String protocol = "我已閱讀並同意本《協議》"; //2.定義你需要的`Span` ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View widget) { // 在這裡實現點選事件 showToast(protocol); } }; //3.使用將要顯示文字,構造一個`SpannableString` SpannableString spannableString = new SpannableString(protocol); //4.呼叫`SpannableString`的`setSpan()`方法設定`span`;`setSpan()`的引數會有設定文字的範圍。 int start = protocol.length() - 4; int end = protocol.length(); spannableString.setSpan(new CustomClickableSpan(protocol), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //5.呼叫`TextView`的`setText()`方法,顯示`SpannableString` mTextView.setText(spannableString); //6.這裡比平常的Span多一步,要設定一下超連結,否則不會生效 mTextView.setMovementMethod(LinkMovementMethod.getInstance());
效果圖如下:
雖然上面實現了基本的點選功能,但是美工”《協議》”這兩個字的顏色是藍色,而且不想要下劃線;所以還要進一步處理,這就需要看看ClickableSpan
的內部是如何處理文字顏色了。它的原始碼如下:
public abstract class ClickableSpan extends CharacterStyle implements UpdateAppearance { public abstract void onClick(View widget); @Override public void updateDrawState(TextPaint ds) { ds.setColor(ds.linkColor); ds.setUnderlineText(true); } }
上面的程式碼顯示,它在updateDrawState()
方法裡面,設定裡字型的顏色和下劃線。所以我們需要繼承ClickableSpan
重寫一下這個方法,在這個方法裡面,設定我們希望的顏色。程式碼如下:
private class CustomClickableSpan extends ClickableSpan {
private String msg;
public CustomClickableSpan(String msg) {
this.msg = msg;
}
@Override
public void onClick(View widget) {
showToast(msg);
}
@Override
public void updateDrawState(TextPaint ds) {//在這裡設定需要的顏色和是否需要下滑線
ds.setColor(getResources().getColor(R.color.color_blue));
ds.setUnderlineText(false);
}
}
我可以替換之前的第四步:
//4.呼叫`SpannableString`的`setSpan()`方法設定`span`;`setSpan()`的引數會有設定文字的範圍。
int start = protocol.length() - 4;
int end = protocol.length();
spannableString.setSpan(new CustomClickableSpan(protocol), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
效果圖如下:
這樣就更換了顏色,去掉了下劃線。
實現了TextView區域性點選的問題,我們來說說其它的Span
。
AlignmentSpan.Standard 實現文字的左/右對齊,居中對齊
TextView 文字的對齊方式有三種,對應的是
Layout.Alignment
中的三個列舉常量
- TextView 預設是左對齊的,對應的引數是
Layout.Alignment.ALIGN_NORMAL
- 右對齊,即跟預設相反,對應的引數是
Layout.Alignment.ALIGN_OPPOSITE
- 居中對齊的,對應的引數是
Layout.Alignment.ALIGN_CENTER
下面我們按照最開始的步驟一步一步設定Span
//1.定義需要顯示的文字
String text = "Sometimes I really doubt whether there is love between my parents. " +
"Every day they are very busy trying to earn money in order to pay the high tuition for my brother and me. " +
"They don't act in the romantic ways that I read in books or I see on TV.";
//2.定義你需要的`Span`
AlignmentSpan.Standard alignmentSpan = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
//3.使用將要顯示文字,構造一個`SpannableString`
SpannableString spannableString = new SpannableString(text);
//4.呼叫`SpannableString`的`setSpan()`方法設定`span`;`setSpan()`的引數會有設定文字的範圍。
spannableString.setSpan(alignmentSpan, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//5.呼叫`TextView`的`setText()`方法,顯示`SpannableString`
mTextView.setText(spannableString);
這裡設定文字的對齊方式,是作用到段落上的,所以在設定 start 和 end 範圍時要注意,設定幾個範圍的內的字元,是沒有反應得。
上面程式碼的效果如圖所示:
如果要實現居中對齊可在第2步定義Span的時候,把引數設定成
Layout.Alignment.ALIGN_CENTER
UnderlineSpan 實現文字下劃線的功能
我們這裡如要給TextView
的文字加上下劃線,只需要重複上面的5個步驟,並且替換第2步就Ok了。
//2.定義你需要的`Span`
UnderlineSpan underlineSpan = new UnderlineSpan();
然後把它UnderlineSpan
的引用傳給SpannableString
的setSpan()
方法就Ok了。
StrikethroughSpan 實現刪除線 功能
同樣我只需要將定義 StrikethroughSpan
,然後將其引用傳遞給SpannableString
的setSpan()
方法就Ok了。
//2.定義你需要的`Span`
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
以下如果沒有特殊說明,我們都是重複上面的步驟,只是修改了第二步。
ImageSpan 替換指定位置跟指定長度的字元
//2.定義你需要的`Span`
ImageSpan imageSpan = new ImageSpan(this,R.drawable.ic_launcher);
//……省略第3步
//4.這裡會把從20-30的字元替換為圖片
spannableString.setSpan(imageSpan, 20, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ImageSpan 還有多個構造方法,主要還有傳入
Bitmap
和Drawable
。
SubscriptSpan 把字元變成下標
//2.定義你需要的`Span`
SubscriptSpan span = new SubscriptSpan();
//3.使用將要顯示文字,構造一個`SpannableString`
SpannableString spannableString = new SpannableString(text);
//4.將第19到第24個字元設成下標
spannableString.setSpan(span, 19, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
效果圖如下:
SuperscriptSpan 把字元變成上角標
//2.定義你需要的`Span`
SuperscriptSpan span = new SuperscriptSpan ();
//3.使用將要顯示文字,構造一個`SpannableString`
SpannableString spannableString = new SpannableString(text);
//4.將第19到第24個字元設成上角標
spannableString.setSpan(span, 19, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
效果圖如下:
StyleSpan 設定文字的樣式
StyleSpan 設定的內容相當於在 佈局 裡設定
android:textStyle
//2.定義一個StyleSpan,並且設定 文字為粗體
StyleSpan span = new StyleSpan(Typeface.BOLD);
除了粗體,還有其它風格:
ITALIC
斜體
BOLD_ITALIC
粗斜體
TextView 預設的格式 NORMAL
TypefaceSpan 設定文字的文體,
引數為Android內建的文字字型家族。包含”normal”,”sans”,”serif”,”monospace”,”sans-serif-light” 等
//2.定義你需要的`Span`
TypefaceSpan span = new TypefaceSpan("serif");
TextAppearanceSpan 可以在 style
檔案裡自定義文字的風格
//2.定義你需要的`Span`
TextAppearanceSpan span = new TextAppearanceSpan (this,R.style.TextAppearanceSpan);
RelativeSizeSpan 設定指定文字相對於其它文字的大小
//2.這裡設定的是指定範圍內的文字是其他文字大小的2倍
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(2.0f);
相對的還有
AbsoluteSizeSpan
,這個指定是文字的絕對大小,引數設定的是絕對的大小//2.設定文字的絕對大小,並且設定單位為 dip AbsoluteSizeSpan span = new AbsoluteSizeSpan(24, true);
ScaleXSpan 設定指定文字 在 x 軸方向縮放的大小
//2橫向放大2倍;橫向縮小應該小於 1.0f。
ScaleXSpan scaleXSpan = new ScaleXSpan(2.0f);
還剩下幾個 Span
,大家可自己嘗試一下,看看能出現什麼效果。
另外 在這行程式碼中
spannableString.setSpan(imageSpan, 20, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
最後一個引數,會在獲取字元長度時用到。這裡用到的是 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
,表示不包含start位置的字元也不含end位置的字元。除了這個還有其他三個引數:
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
(包括start,不包括end)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE
(不包括start,包括end)
Spanned.SPAN_INCLUSIVE_INCLUSIVE
(start、end 都包括)。