前言
SpannableString,是google提供用來處理富文本的功能類.支持很多文本內容的效果變化.另外,它也是Android實現富文本編輯器的關鍵.
關鍵API詳解
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
這是一個簡單使用的demo,我們用這個demo來講解一些關鍵點.
這行代碼的關鍵是setSpan(Object what, int start, int end, int flags)方法,這個方法在后面的文字處理將會一直使用到. setSpan有四個參數我們一個一個來講解:
第一個參數 Object what 這個參數主要是提供你需要改變字符串的效果實現類,后續會一一講解並且給出效果圖
第二個參數 int start 這個參數是需要改變的字符串的起始位置
第三個參數 int end 這個參數是需要改變的字符串的結束位置
第四個參數 int flags 是一些字符串新增效果的影響范圍,您可以參考這篇博客https://www.jianshu.com/p/1956e15c9a27這位大神講解的十分詳細了.本着就算是看懂了也要敲一敲代碼記錄的想法,下面也會說明一下常用的4種方法
public static final int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK;
在前面/范圍內增加字符,新增字符會跟隨效果.
在后面增加字符,新增字符不會跟隨效果
效果圖:

public static final int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;
在前面/范圍內/后面增加字符,新增字符會跟隨效果.
效果圖:

public static final int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;
在范圍內增加字符,新增字符會跟隨效果.
在前面/后面增加字符,新增字符不會跟隨效果
效果圖:

public static final int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;
在范圍內/后面增加字符,新增字符會跟隨效果.
在前面增加字符,新增字符不會跟隨效果.
效果圖:

代碼里還有一些其他的常量,但是測試后其他都是這四種基本里一樣的效果.也實在是沒看懂google的注釋.....
文字顏色
以下代碼將一段文字變成紅色
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
ForegroundColorSpan 注意這個類是關鍵,他實現文字顏色改變.
效果圖:

文字背景顏色
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new BackgroundColorSpan(Color.parseColor("#FFFF0C00")) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
BackgroundColorSpan 注意這個類是關鍵,他實現文字背景顏色改變.
效果圖:

字體
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new TypefaceSpan("sans-serif") //new TypefaceSpan(Typeface.SANS_SERIF) 或者使用這個方法 , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖(系統自帶的演示字體效果不明顯):

字體大小
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new AbsoluteSizeSpan(50) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

粗體
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.BOLD) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

斜體
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.ITALIC) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

粗體和斜體
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC) , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
另外還有一個Typeface.NORMAL 正常值就不演示了
效果圖:

刪除線
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new StrikethroughSpan() , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

下划線
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new UnderlineSpan() , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

上標
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new SuperscriptSpan() , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

下標
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new SubscriptSpan() , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

插入圖片
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); ImageSpan span = new ImageSpan(bitmap); SpannableString spannableString = new SpannableString(content); spannableString.setSpan(span , 0 , 1 , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
或者
String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher, null); //讀取圖片 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());//設置邊界 圖片顯示范圍 ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);//ImageSpan.ALIGN_BASELINE 是對齊方式,這個是基線對齊 SpannableString spannableString = new SpannableString(content); spannableString.setSpan(span , 0 , 1 , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
效果圖:

點擊事件
mTextView.setMovementMethod(LinkMovementMethod.getInstance());//這是關鍵,只有TextView添加這個后才能有點擊事件 mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改點擊后的背景色 String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(@NonNull View widget) { Toast.makeText(MainActivity.this, "你點擊了創業未半", Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(@NonNull TextPaint ds) { //改變選中文字的顏色或者樣式,注意這里的TextPaint 其實是Paint,可以參考Paint的繪制添加其他效果. ds.setColor(Color.RED); // super.updateDrawState(ds); } }; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(clickableSpan , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
setMovementMethod是重中之重,只有設置了才能有 點擊功能
效果圖:

超鏈接
電話
mTextView.setMovementMethod(LinkMovementMethod.getInstance());//這是關鍵,只有TextView添加這個后才能有點擊事件 mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改點擊后的背景色 String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。"; SpannableString spannableString = new SpannableString(content); spannableString.setSpan(new URLSpan("tel:10086") , content.indexOf("創業") , content.indexOf("而中") , Spanned.SPAN_INCLUSIVE_EXCLUSIVE); mTextView.setText(spannableString);
注意!使用超鏈接,依然要設置setMovementMethod,另外URLSpan也是可以重寫點擊事件的.
效果圖:

與使用Intent的超鏈接類似,也是支持幾個通用的超鏈接,都需要你輸入正確的前綴
mailto:123456@qq.comhttp://www.baidu.comsms:123456mms:123456geo: 38.899533,-77.036476
其他Span
上面的span只是一些常用的span演示,但是其實還有更多的span可以選擇和使用,他們都在
這個目錄中.在這個目錄下還有以下這些span.如果后續有時間我會一一實驗使用這些span以判斷他們的功能.

放棄富文本效果,提取文本
之前有端時間苦惱怎么提取不帶富文本格式的文本,因為源代碼的有很多方法並沒有注釋,所以蛋疼了很久..,后面突然發現,直接使用toString()方法就行
spannableString.toString()
END
