SpannableString
String字符串盆繁,這個咱們經常用掀淘,一定很熟悉,而這個SpanableString這個就不常用了油昂,其實它們都可以表示字符串革娄,只不過后者可以輕松地利用官方提供的Api對字符串進行各種風格的設置。
日常開發(fā)中都有哪些應用場景呢冕碟?比如:
- 顯示的文字加上下劃線拦惋、中劃線、斜體安寺、加粗等
- 給TextView中部分文字加上點擊事件或顏色背景
- TextView中部分文字需要顯示的字體大厕妖,部分文字需要顯示的字體小
- TextView中的文字可要求顯示表情符號(在聊天應用中經常會出現)等等等
這點需求雖說實現起來不是什么難事,不過選擇一個好的方案挑庶,可以事半功倍言秸。接下來介紹今天的主角:SpannableString
先看看官方怎么定義這個類的
This is the class for text whose content is immutable but to which markup objects can be attached and detached. For mutable text, see SpannableStringBuilder.
大體意思是:這是文本的類,該文本的內容是不可變的挠羔,但可以附加和分離標記對象井仰。對于可變文本,請參見SpannableStringBuilder破加。
這個類源碼很少俱恶,100行代碼都不到,感興趣的可以去看看范舀。其中有一個核心方法:setSpan(what,start,end,flags)共有4個參數
- what:是一個Object對象合是,用來設置字符串的顯示風格(其中官方已經給我們提供一些常用的Span類,當然也可以自己定義了)
- sart:從字符串的第幾位開始锭环,設置的風格起作用
- end:設置的風格到第幾位后聪全,不在起作用;其實與start構成了一個作用區(qū)間
- flags:有四種形式辅辩,就是確定作用空間是否包括收尾难礼,待會說
常用的Span類有:
- BackgroundColorSpan 背景色
- ClickableSpan 文本可點擊,有點擊事件
- ForegroundColorSpan 文本顏色(前景色)
- MaskFilterSpan 修飾效果玫锋,如模糊(BlurMaskFilter)蛾茉、浮雕(EmbossMaskFilter)
- MetricAffectingSpan 父類,一般不用
- RasterizerSpan 光柵效果
- StrikethroughSpan 刪除線(中劃線)
- SuggestionSpan 相當于占位符
- UnderlineSpan 下劃線
- AbsoluteSizeSpan 絕對大辛寐埂(文本字體)
- DynamicDrawableSpan 設置圖片谦炬,基于文本基線或底部對齊。
- ImageSpan 圖片
- RelativeSizeSpan 相對大小(文本字體)
- ReplacementSpan 父類键思,一般不用
- ScaleXSpan 基于x軸縮放
- StyleSpan 字體樣式:粗體础爬、斜體等
- SubscriptSpan 下標(數學公式會用到)
- SuperscriptSpan 上標(數學公式會用到)
- TextAppearanceSpan 文本外貌(包括字體、大小吼鳞、樣式和顏色)
- TypefaceSpan 文本字體
- URLSpan 文本超鏈接
flags共有四種屬性:
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE 從起始下標到終了下標看蚜,包括起始下標
- Spanned.SPAN_INCLUSIVE_INCLUSIVE從起始下標到終了下標,同時包括起始下標和終了下標
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE從起始下標到終了下標赖条,但都不包括起始下標和終了下標
- Spanned.SPAN_EXCLUSIVE_INCLUSIVE 從起始下標到終了下標失乾,包括終了下標
事例
-
ForegroundColorSpan :給一段文字中個別的字設置顏色,這個比較常用了
ForegroundColorSpan纬乍,為文本設置前景色碱茁,效果和TextView的setTextColor()類似,不過如果用setTextColor()估計得用TextView拼接或者用到Html類加載html片段實現仿贬。ForegroundColorSpan纽竣,實現如下:
TextView txtInfo = findViewById(R.id.textView);
SpannableString span = new SpannableString("設置前背景色");
span.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorPrimary)),3, 5, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
txtInfo.setMovementMethod(LinkMovementMethod.getInstance());
txtInfo.setHighlightColor(getResources().getColor(android.R.color.transparent));
txtInfo.setText(span);
-
ImageSpan:在文字中顯示表情符號(其實就是設置圖片)
如果對一段文字中特殊文字進行處理,就可以實現聊天效果中帶有表情符茧泪。
怎么實現呢蜓氨,代碼如下,其實我們知道有這個用法就行了
TextView tv8 = findViewById(R.id.tv8);
SpannableString spanStr8 = new SpannableString("文字里添加表情(表情)");
Drawable image = getResources().getDrawable(R.mipmap.ic_launcher);
image.setBounds(new Rect(0,0,50,50));
spanStr8.setSpan(new ImageSpan(image),5, 7,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv8.setText(spanStr8);
-
ClickableSpan:可以為文字加上點擊事件队伟,比如常見的:
實現方式:
SpannableString spanStr10 = new SpannableString("請準守協(xié)議《XXXXXX協(xié)議》");
spanStr10.setSpan(new ClickableSpan() {
@Override
public void onClick(View view) {
//點擊事件
Toast.makeText(MainActivity.this,"點擊了我穴吹,可以寫跳轉邏輯",Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.parseColor("#ff4d40"));
}
},5,spanStr10.length(),Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv10.setMovementMethod(LinkMovementMethod.getInstance()); // 必須的設置這個,不然點擊效果 不生效
tv10.setHighlightColor(Color.parseColor("#ffffff")); //點擊后顯示的背景色嗜侮,我這里設置了白色港令,默認顏色不好看
tv10.setText(spanStr10);
還有其它一些常規(guī)用法,我就不一一列舉了锈颗,上圖:
github地址:https://github.com/A-How/SpanableStringDemo/tree/master
SpanableStringBuilder
定義字符串用String,對于大量字符串進行拼接顷霹,我們可以使用StringBuilder進行處理;SpanableStringBuilder也是對大量SpanableString拼接進行處理的击吱,也同樣使用append方法淋淀。舉個例子:
代碼實現
String beforeText = "快快下單";
String afterText = "(立享200元優(yōu)惠)";
int beforeSize = 20;
int afterSize = 15;
SpannableStringBuilder builder = new SpannableStringBuilder(beforeText);
builder.setSpan(new ForegroundColorSpan(Color.parseColor("#ffdf40")),0,beforeText.length(),Spanned.SPAN_INCLUSIVE_INCLUSIVE);
builder.setSpan(new AbsoluteSizeSpan(beforeSize,true),0,beforeText.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
builder.append(afterText);
builder.setSpan(new ForegroundColorSpan(Color.parseColor("#ff6940")),beforeText.length(),builder.length(),Spanned.SPAN_INCLUSIVE_INCLUSIVE);
builder.setSpan(new AbsoluteSizeSpan(afterSize,true),beforeText.length(),builder.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tv12.setText(builder);
后續(xù)我會繼續(xù)添加一些關于SpanableString一些Span類的用法,
github地址:https://github.com/A-How/SpanableStringDemo/tree/master