Android SpannableString详细解析
文章目录
-
- 什么是SpannableString?
- 各种Span
- ForegroundColorSpan 前景色
- BackgroudColorSpan 背景色
- ClickableSpan 点击事件
- URLSpan 超链接
- MaskFilterSpan 模糊 浮雕
- RelativeSizeSpan 字体相对大小
- AbsoluteSizeSpan 字体绝对大小
- ScaleXSpan 字体x轴缩放
- StyleSpan 样式
- TypefaceSpan 字体
- TextAppearanceSpan 文字外貌
- UnderlineSpan 下划线
- StrikethroughSpan 删除线
- SuperscriptSpan 上标
- SubscriptSpan 下标
- ImageSpan 图片
- 总结
什么是SpannableString?
SpannableString,是CharSequence的一种,原本的CharSequence只是一串字符序列,没有任何样式,而SpannableString
可以在字符序列基础上对指定的字符进行润饰,在开发中,TextView可以通过setText(CharSequence)
传入SpannableString
作为参数,来达到显示不同样式文字的效果。
创建方式
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
- 1
如何对SpannableString
进行润饰?
一般通过以下方式进行设置
spannableString.setSpan(Object what, int start, int end, int flags);
- 1
这里讲解一下几个参数的意义
- what:对SpannableString进行润色的各种
Span
; - int:需要润色文字段开始的下标;
- end:需要润色文字段结束的下标;
- flags:决定开始和结束下标是否包含的标志位,有四个参数可选
- SPAN_INCLUSIVE_EXCLUSIVE:包括开始下标,但不包括结束下标
- SPAN_EXCLUSIVE_INCLUSIVE:不包括开始下标,但包括结束下标
- SPAN_INCLUSIVE_INCLUSIVE:既包括开始下标,又包括结束下标
- SPAN_EXCLUSIVE_EXCLUSIVE:不包括开始下标,也不包括结束下标
这里涉及到一个重要的角色,就是各种各样的span,它决定我们要对文字的进行怎样的润饰,而后三个参数决定润饰哪些文字,为了方便起见,后面的flags默认都使用SPAN_INCLUSIVE_EXCLUSIVE模式。
各种Span
先来看一张类结构图,了解各种Span之间的关系
可以看出所有Span都继承于CharacterStyle这个抽象类,另外MetricAffectingSpan、ReplacementSpan和ClickableSpan都是抽象类,下面展示一些常用的Span
ForegroundColorSpan 前景色
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.GREEN);
spannableString.setSpan(foregroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
ForegroundColorSpan:前景色,也就是对文字上色,颜色设置为GREEN,start为4,end为7,应该是“陈奕迅”三个字显示为绿色,看一下实际效果
BackgroudColorSpan 背景色
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);
spannableString.setSpan(backgroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
BackgroudColorSpan:与ForegroundColorSpan类似,对文字背景上色
ClickableSpan 点击事件
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "如果我是陈奕迅", Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
};
spannableString.setSpan(clickableSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
ClickableSpan:是一个抽象类,实现可点击效果,可以重写onClick方法实现点击事件,这里点击“陈奕迅”三个字简单地弹toast
URLSpan 超链接
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
URLSpan urlSpan = new URLSpan("https://www.baidu.com/s?ie=UTF-8&wd=陈奕迅");
spannableString.setSpan(urlSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
URLSpan:实现超链接的效果,继承于ClickableSpan,点击实现跳转到浏览器
MaskFilterSpan 模糊 浮雕
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
MaskFilterSpan embossMaskFilterSpan =
new MaskFilterSpan(new EmbossMaskFilter(new float[]{10, 10, 10}, 0.5f, 1, 1));
spannableString.setSpan(embossMaskFilterSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);
spannableString.setSpan(relativeSizeSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(10, Blur.NORMAL));
spannableString.setSpan(blurMaskFilterSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
MaskFilterSpan:构造方法接受MaskFilter作为参数,其中它有两个子类:EmbossMaskFilter和BlurMaskFilter
EmbossMaskFilter实现浮雕效果
EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
- 1
- direction:float数组,定义长度为3的数组标量[x,y,z],来指定光源的方向
- ambient:环境光亮度,0~1
- specular:镜面反射系数
- blurRadius:模糊半径,必须>0
BlurMaskFilter实现模糊效果
BlurMaskFilter(float radius, Blur style)
- 1
- radius:模糊半径
- style:有四个参数可选
- BlurMaskFilter.Blur.NORMAL:内外模糊
- BlurMaskFilter.Blur.OUTER:外部模糊
- BlurMaskFilter.Blur.INNER:内部模糊
- BlurMaskFilter.Blur.SOLID:内部加粗,外部模糊
RelativeSizeSpan 字体相对大小
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);
spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
RelativeSizeSpan:设置字体的相对大小,这里设置为TextView大小的1.5倍,看图
AbsoluteSizeSpan 字体绝对大小
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(40, true);
spannableString.setSpan(absoluteSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
AbsoluteSizeSpan:设置字体的相绝对大小,40表示文字大小,true表示单位为dip,若为false则表示px
ScaleXSpan 字体x轴缩放
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
ScaleXSpan scaleXSpan= new ScaleXSpan(1.5f);
spannableString.setSpan(scaleXSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
ScaleXSpan:设置字体x轴缩放,1.5表示x轴放大为1.5倍,效果如图
StyleSpan 样式
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
StyleSpan italicSpan = new StyleSpan(Typeface.ITALIC);
StyleSpan boldItalicSpan = new StyleSpan(Typeface.BOLD_ITALIC);
spannableString.setSpan(boldSpan, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(italicSpan, 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(boldItalicSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
StyleSpan:设置文字样式,如斜体、粗体
TypefaceSpan 字体
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
TypefaceSpan monospace = new TypefaceSpan("monospace");
TypefaceSpan serif = new TypefaceSpan("serif");
TypefaceSpan sans_serif = new TypefaceSpan("sans-serif");
spannableString.setSpan(monospace, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(serif, 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sans_serif, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
TypefaceSpan:设置文字字体类型,如monospace、serif和sans-serif等等
TextAppearanceSpan 文字外貌
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(this, android.R.style.TextAppearance_Material);
spannableString.setSpan(textAppearanceSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
TextAppearanceSpan:设置文字外貌,通过style资源设置,这里使用系统的style资源
UnderlineSpan 下划线
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
UnderlineSpan:设置文字下划线,强调突出文字时可以使用该span
StrikethroughSpan 删除线
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
StrikethroughSpan:设置文字删除线
SuperscriptSpan 上标
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
SuperscriptSpan superscriptSpan = new SuperscriptSpan();
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(0.8f);
spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(superscriptSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
SuperscriptSpan:设置文字为上标
SubscriptSpan 下标
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
SubscriptSpan subscriptSpan = new SubscriptSpan();
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(0.8f);
spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(subscriptSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
- 5
- 6
SubscriptSpan:设置文字为下标
ImageSpan 图片
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
ImageSpan imageSpan = new ImageSpan(this, R.drawable.ic_eason);
spannableString.setSpan(imageSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
- 1
- 2
- 3
- 4
ImageSpan:设置图片
总结
总结一下以上提到的Span
- ForegroundColorSpan:前景色
- BackgroundColorSpan:背景色
- ClickableSpan:抽象类,可点击效果,重写onClick方法响应点击事件
- URLSpan:超链接
- MaskFilterSpan:EmbossMaskFilter浮雕效果,BlurMaskFilter模糊效果
- RelativeSpan:文字相对大小
- AbsoluteSpan:文字绝对大小
- ScaleXSpan:x轴缩放
- styleSpan:文字样式
- TypefaceSpan:文字字体类型
- TextApearanceSpan:文字外貌
- UnderlineSpan:下划线
- StrikeThroughSpan:删除线
- SuperscriptSpan:上标
- SubscriptSpan:下标
- ImageSpan:图片
作者:CharmingWong
链接:https://www.jianshu.com/p/472fd3e32324
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
文章来源: blog.csdn.net,作者:yechaoa,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/yechaoa/article/details/109360081
- 点赞
- 收藏
- 关注作者
评论(0)