情景
使用一个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);
}
}