Android中各種Span的用法
前言
SpannableStringBuilder
URLSpan
UnderlineSpan
TypefaceSpan
TextAppearanceSpan
TabStopSpanStandard
SuperscriptSpan
SubscriptSpan
StrikethroughSpan
ScaleXSpan
StyleSpan
RelativeSizeSpan
QuoteSpan
MaskFilterSpan
LeadingMarginSpanStandard
ImageSpan
IconMarginSpan
ForegroundColorSpan
DrawableMarginSpan
BulletSpan
BackgroundColorSpan
AlignmentSpanStandard
AbsoluteSizeSpan
ClickableSpan
源代碼
前言
在android.text.style包下,有一些Span類,可以提供我們完成一些在TextView中的特殊内容。(比如:部分内容顔色、字型、大小不同等等,更有部分字型可點選。)
還有一個SpannableStringBuilder,可以幫助我們設定Span。
底下也有全部的源代碼。
SpannableStringBuilder
SpannableStringBuilder可以友善我們更好的設定上對應的Span。
設定Span
SpannableStringBuilder.setSpan(Object what, int start, int end, int flags)
這裡的Flag表示:start和end是開區間還是閉區間。
Flag:
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE —— (a,b)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE —— (a,b]
Spanned.SPAN_INCLUSIVE_EXCLUSIVE —— [a,b)
Spanned.SPAN_INCLUSIVE_INCLUSIVE —— [a,b]
URLSpan
功能:點選文字,可以打開一個URL。
URLSpan(String url)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new URLSpan("https://github.com/CaMnter"), start, sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
// 在單擊連結時凡是有要執行的動作,都必須設定MovementMethod對象
contentTV.setMovementMethod(LinkMovementMethod.getInstance());
// 設定點選後的顔色,這裡涉及到ClickableSpan的點選背景
contentTV.setHighlightColor();
URLSpan
UnderlineSpan
功能:設定文字下劃線。
UnderlineSpan()
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new UnderlineSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
UnderlineSpan
TypefaceSpan
功能:設定文字字型。
TypefaceSpan(String family)構造方法源碼中的注釋提示了三種系統字型:
monospace
serif
sans-serif
/**
* @param family The font family for this typeface. Examples include
* "monospace", "serif", and "sans-serif".
*/
public TypefaceSpan(String family) {
mFamily = family;
}
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new TypefaceSpan("serif"), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
TypefaceSpan
TextAppearanceSpan
功能:設定文字字型、文字樣式(粗體、斜體、等等)、文字顔色狀态、文字下劃線顔色狀态等等。
TextAppearanceSpan的三個構
TextAppearanceSpan(Context context, int appearance)
TextAppearanceSpan(Context context, int appearance, int colorList)
TextAppearanceSpan(String family, int style, int size,ColorStateList color, ColorStateList linkColor)
monospace
serif
sans-serif
style:
Typeface.NORMAL
Typeface.BOLD
Typeface.ITALIC
Typeface.BOLD_ITALIC
size:表示字型大小(機關px)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ColorStateList colorStateList = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
colorStateList = this.activity.getColorStateList(R.color.selector_apperarance_span);
} else {
try {
colorStateList = ColorStateList.createFromXml(this.activity.getResources(), this.activity.getResources().getXml(R.color.selector_apperarance_span));
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
}
ssb.setSpan(new TextAppearanceSpan("serif", Typeface.BOLD_ITALIC, this.activity.getResources().getDimensionPixelSize(R.dimen.text_appearance_span), colorStateList, colorStateList), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
TextAppearanceSpan
TabStopSpan.Standard
功能:每行的MarginLeft的偏移量(跟 \t 和 \n 有關系)。
TabStopSpan.Standard(int where)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
String[] subs = content.split(" ");
ssb = new SpannableStringBuilder();
/**
* TabStopSpan. Standard related to \t and \n
* TabStopSpan.Standard 跟 \t 和 \n 有關系
*/
for (String sub1 : subs) {
ssb.append("\t").append(sub1).append(" ");
ssb.append("\n");
}
ssb.setSpan(new TabStopSpan.Standard(), , ssb.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
TabStopSpan.Standard
SuperscriptSpan
功能:文字設定為上标,數學公式中用到。
SuperscriptSpan(Parcel src)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), "Save6");
Parcel parcel = Parcel.obtain();
parcel.writeInt();
int sixPosition = ssb.toString().indexOf("6");
ssb.setSpan(new SuperscriptSpan(parcel), sixPosition, sixPosition + , Spanned.SPAN_INCLUSIVE_INCLUSIVE);
parcel.recycle();
contentTV.setText(ssb);
SuperscriptSpan
SubscriptSpan
功能:文字設定為下标,化學式中用到。
SubscriptSpan(Parcel src)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), "Save6");
Parcel parcel = Parcel.obtain();
parcel.writeInt();
int sixPosition = ssb.toString().indexOf("6");
ssb.setSpan(new SubscriptSpan(parcel), sixPosition, sixPosition + , Spanned.SPAN_INCLUSIVE_INCLUSIVE);
parcel.recycle();
contentTV.setText(ssb);
SubscriptSpan
StrikethroughSpan
功能:文字設定删除線。
StrikethroughSpan()
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new StrikethroughSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
StrikethroughSpan
ScaleXSpan
功能:文字橫向縮放。
ScaleXSpan(float proportion)
proportion:縮放比例
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new ScaleXSpan(f), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
ScaleXSpan
StyleSpan
功能:文字設定樣式(正常、粗體、斜體、粗斜體)。
StyleSpan(int style)
style:
Typeface.NORMAL
Typeface.BOLD
Typeface.ITALIC
Typeface.BOLD_ITALIC
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
StyleSpan
RelativeSizeSpan
功能:設定文字相對大小,指相對于文本設定的大小的相對比例。
RelativeSizeSpan(float proportion)
proportion:大小比例。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new RelativeSizeSpan(f), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
RelativeSizeSpan
QuoteSpan
功能:設定文字左側顯示引用樣式(一條豎線)。
QuoteSpan(@ColorInt int color)
color:豎線的顔色。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new QuoteSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
QuoteSpan
MaskFilterSpan
功能:設定文字模糊效果和浮雕效果。
MaskFilterSpan(MaskFilter filter)
MaskFilter:
BlurMaskFilter: 模糊效果
EmbossMaskFilter: 浮雕效果
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
MaskFilterSpan embossMaskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{, , }, f, , ));
ssb.setSpan(embossMaskFilterSpan, start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
String you = "you";
int indexYou = content.indexOf(you);
MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(, BlurMaskFilter.Blur.OUTER));
ssb.setSpan(blurMaskFilterSpan, indexYou, indexYou + you.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
MaskFilterSpan
LeadingMarginSpan.Standard
功能:設定文本縮進。
LeadingMarginSpan.Standard(int first, int rest)
first:首行的 margin left 偏移量。
rest:其他行的 margin left 偏移量。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.append(" ")
.append(ssb.toString())
.append(ssb.toString())
.append(ssb.toString());
ssb.setSpan(new LeadingMarginSpan.Standard(, ), , ssb.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
LeadingMarginSpan.Standard
ImageSpan
功能:文本插入圖檔。
構造方法很多:
ImageSpan(Context context, Bitmap b)
ImageSpan(Context context, Bitmap b, int verticalAlignment)
ImageSpan(Drawable d)
ImageSpan(Drawable d, int verticalAlignment)
ImageSpan(Drawable d, String source)
ImageSpan(Drawable d, String source, int verticalAlignment)
ImageSpan(Context context, Uri uri)
ImageSpan(Context context, Uri uri, int verticalAlignment)
ImageSpan(Context context, @DrawableRes int resourceId)
ImageSpan(Context context, @DrawableRes int resourceId, int verticalAlignment)
verticalAlignment:
ImageSpan.ALIGN_BOTTOM
ImageSpan.ALIGN_BASELINE
source:圖檔的本機路徑String。( xxx/xxx/xxx.jpg )
uri:圖檔的本機uri。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), " Save");
ssb.setSpan(new ImageSpan(this.activity, R.mipmap.ic_mm_1, ImageSpan.ALIGN_BASELINE), , , Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
ImageSpan
IconMarginSpan
功能:文本插入圖檔+Margin。
IconMarginSpan(Bitmap b, int pad)
pad:margin偏移量。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
Bitmap bitmap = BitmapFactory.decodeResource(this.activity.getResources(), R.mipmap.ic_mm_1);
ssb.setSpan(new IconMarginSpan(bitmap, ), , , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//bitmap.recycle();
contentTV.setText(ssb);
IconMarginSpan
ForegroundColorSpan
功能:設定文字顔色。
ForegroundColorSpan(@ColorInt int color)
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new ForegroundColorSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
ForegroundColorSpan
DrawableMarginSpan
功能:文本插入圖檔+Margin。
DrawableMarginSpan(Drawable b, int pad)
pad:margin偏移量。
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new DrawableMarginSpan(ResourcesUtil.getDrawable(this.activity, R.mipmap.ic_mm_1), ), , , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTV.setText(ssb);
DrawableMarginSpan
BulletSpan
功能:類似于HTML中的
- 标簽的圓點效果。
-
BulletSpan(int gapWidth, int color)
gapWidth:圓點與文本的間距。
color:圓點顔色。
SpannableStringBuilder ssb = new SpannableStringBuilder(content); ssb.setSpan(new BulletSpan(, ), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); contentTV.setText(ssb);
BulletSpan
BackgroundColorSpan
功能:設定背景色。
BackgroundColorSpan(int color)
SpannableStringBuilder ssb = new SpannableStringBuilder(content); String you = "you"; int indexYou = content.indexOf(you); ssb.setSpan(new BackgroundColorSpan(), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ssb.setSpan(new BackgroundColorSpan(), indexYou, indexYou + you.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); contentTV.setText(ssb);
BackgroundColorSpan
AlignmentSpan.Standard
功能:設定文字對齊方式。
AlignmentSpan.Standard(Layout.Alignment align)
align:
Layout.Alignment.ALIGN_NORMAL
Layout.Alignment.ALIGN_OPPOSITE
Layout.Alignment.ALIGN_CENTER
Layout.Alignment.ALIGN_LEFT
Layout.Alignment.ALIGN_RIGHT
SpannableStringBuilder ssb = new SpannableStringBuilder(content); ssb.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), , ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); contentTV.setText(ssb);
AbsoluteSizeSpan
功能:設定文字絕對大小。
AbsoluteSizeSpan(int size, boolean dip)
size:預設機關為px。
dip:true為size的機關是dip,false為px。
SpannableStringBuilder ssb = new SpannableStringBuilder(content); ssb.setSpan(new AbsoluteSizeSpan(, true), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); contentTV.setText(ssb);
AbsoluteSizeSpan
ClickableSpan
功能:文字可點選。
抽象類,需要自己擴充實作。
ClickableSpanNoUnderline
SpanClickableSpanpublic class ClickableSpanNoUnderline extends ClickableSpan { private static final String TAG = "ClickableSpan"; private static final int NO_COLOR = -; private int color; private OnClickListener onClickListener; public ClickableSpanNoUnderline(int color, OnClickListener onClickListener) { super(); this.color = color; this.onClickListener = onClickListener; } public ClickableSpanNoUnderline(OnClickListener onClickListener) { this(NO_COLOR, onClickListener); } /** * Makes the text underlined and in the link color. * * @param ds */ @Override public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); // 設定文字顔色 if (this.color == NO_COLOR) { ds.setColor(ds.linkColor); } else { ds.setColor(this.color); } ds.clearShadowLayer(); // 去除下劃線 ds.setUnderlineText(false); ds.bgColor = Color.TRANSPARENT; } /** * Performs the click action associated with this span. * * @param widget widget */ @Override public void onClick(View widget) { if (this.onClickListener != null) { this.onClickListener.onClick(widget, this); } else { Log.w(TAG, "listener was null"); } } /** * 回調接口,回調自身的onClick事件 * 告訴外部 是否被點選 */ public interface OnClickListener<T extends ClickableSpanNoUnderline> { /** * ClickableSpan被點選 * * @param widget widget * @param span span */ void onClick(View widget, T span); } }
開始使用private class SpanClickableSpan extends ClickableSpanNoUnderline { private String urlString; public String getUrlString() { return urlString; } public void setUrlString(String urlString) { this.urlString = urlString; } public SpanClickableSpan(int color, OnClickListener onClickListener) { super(color, onClickListener); } public SpanClickableSpan(OnClickListener onClickListener) { super(onClickListener); } }
SpannableStringBuilder ssb = new SpannableStringBuilder(content); SpanClickableSpan spanClickableSpan = new SpanClickableSpan(, new ClickableSpanNoUnderline.OnClickListener<SpanClickableSpan>() { /** * ClickableSpan被點選 * * @param widget widget * @param span span */ @Override public void onClick(View widget, SpanClickableSpan span) { String urlString = span.getUrlString(); if (TextUtils.isEmpty(urlString)) return; Uri uri = Uri.parse(urlString); 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", "Activity was not found for intent, " + intent.toString()); } } }); spanClickableSpan.setUrlString("https://github.com/CaMnter"); ssb.setSpan(spanClickableSpan, start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); contentTV.setText(ssb); // 在單擊連結時凡是有要執行的動作,都必須設定MovementMethod對象 contentTV.setMovementMethod(LinkMovementMethod.getInstance()); // 設定點選後的顔色,這裡涉及到ClickableSpan的點選背景 contentTV.setHighlightColor();
ClickableSpan
源代碼