情景
使用一個TextView混排多種不同顏色、大小等風格。
效果
SpannableString
這是文本的類,其內容是不可變的,但標記對象可以附加和分離。
This is the class for text whose content is immutable but to which markup objects can be attached and detached.
可以理解爲一個可以設置每個字符風格的String,主要的方法在於setSpan()。
setSpan
/**
* 設置指定區域的風格
*
* @param what 風格類型
* @param start 開始的位置。從0開始,不包含此位置
* @param end 結束位置。包含此位置
* @param flags 可以編輯時風格是否延續
*/
public void setSpan(Object what, int start, int end, int flags)
what 風格
參照: Android中強大的SpannableStringBuilder
- BackgroundColorSpan : 文本背景色
- ForegroundColorSpan : 文本顏色
- MaskFilterSpan : 修飾效果
- RasterizerSpan : 光柵效果
- StrikethroughSpan : 刪除線
- SuggestionSpan : 相當於佔位符
- UnderlineSpan : 下劃線
- AbsoluteSizeSpan : 文本字體(絕對大小)
- DynamicDrawableSpan : 設置圖片,基於文本基線或底部對齊。
- ImageSpan : 圖片
- RelativeSizeSpan : 相對大小(文本字體)
- ScaleXSpan : 基於x軸縮放
- StyleSpan : 字體樣式:粗體、斜體等
- SubscriptSpan : 下標
- SuperscriptSpan : 上標
- TextAppearanceSpan : 文本外貌(包括字體、大小、樣式和顏色)
- TypefaceSpan : 文本字體
- URLSpan : 文本超鏈接
- ClickableSpan : 點擊事件
flags 延續範圍
- SPAN_INCLUSIVE_EXCLUSIVE : 包括前面,不包括後面
- SPAN_INCLUSIVE_INCLUSIVE : 包括前面,包括後面
- SPAN_EXCLUSIVE_EXCLUSIVE
- SPAN_EXCLUSIVE_INCLUSIVE
舉個栗子:
“字”後面,“顏”前面,輸入內容會和“顏色”效果一直,而“色”後面的內容不會改變風格。(腦補畫面…)
SpannableString text = new SpannableString("文字顏色改變");
text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mEditTextColor.setText(text);
效果所有代碼
/**
* SpanableString 類使用
* 實現花式文本的混排
*
* @author fengzhen
* @version v1.0, 2017/10/12 15:41
*/
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edit_text_color)
EditText mEditTextColor;
@BindView(R.id.tv_test_background)
TextView mTvTestBackground;
@BindView(R.id.tv_under_line)
TextView mTvUnderLine;
@BindView(R.id.tv_text_size)
TextView mTvTextSize;
@BindView(R.id.tv_image)
TextView mTvImage;
@BindView(R.id.tv_superscript)
TextView mTvSuperscript;
@BindView(R.id.tv_hyperlink)
TextView mTvHyperlink;
@BindView(R.id.tv_click)
TextView mTvClick;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setTextColor();
setTextBackground();
setTextUnderline();
setTextSize();
setTextImage();
setTextSuperscript();
setTextHyperlink();
setTextClick();
}
private void setTextClick() {
SpannableString text = new SpannableString("文字點擊效果");
text.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "點擊了!", Toast.LENGTH_SHORT).show();
mTvClick.setFocusable(false);
}
@Override
public void updateDrawState(TextPaint ds) {
// 文字顏色
ds.setColor(Color.RED);
// 取消下劃線
ds.setUnderlineText(false);
}
}, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvClick.setText(text);
mTvClick.setMovementMethod(LinkMovementMethod.getInstance());
}
private void setTextHyperlink() {
SpannableString text = new SpannableString("文字超鏈接效果");
text.setSpan(new URLSpan("https://www.baidu.com/?tn=57095150_2_oem_dg"), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvHyperlink.setText(text);
mTvHyperlink.setMovementMethod(LinkMovementMethod.getInstance());
}
private void setTextSuperscript() {
SpannableString text = new SpannableString("文字上標效果");
text.setSpan(new SuperscriptSpan(), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvSuperscript.setText(text);
}
private void setTextImage() {
SpannableString text = new SpannableString("文字變成圖片效果");
text.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvImage.setText(text);
}
private void setTextSize() {
SpannableString text = new SpannableString("文字大小改變");
text.setSpan(new AbsoluteSizeSpan(44), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvTextSize.setText(text);
}
private void setTextUnderline() {
SpannableString text = new SpannableString("文字下劃線效果");
text.setSpan(new UnderlineSpan(), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvUnderLine.setText(text);
}
private void setTextBackground() {
SpannableString text = new SpannableString("文字背景變色");
text.setSpan(new BackgroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvTestBackground.setText(text);
}
private void setTextColor() {
SpannableString text = new SpannableString("文字顏色改變");
text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mEditTextColor.setText(text);
}
}