Span类

# Span: --- `Span` 是强大的标记对象,可用于在字符或段落级别对文本设置样式。通过将 Span 附加到文本对象上,您能够以各种方式更改文本,包括添加颜色、使文本可点击、调整文本大小以及以自定义方式绘制文本。Span 还可以更改 TextPaint 属性、在 Canvas 上绘制,甚至更改文本布局。字体样式可设:大小、放大、前景色、背景色、正常粗体、斜体、粗斜体、下划线、删除线、上标、下标、超链接、电话邮件、网络、短信、彩信、地图、缩放、效果模糊、效果浮雕、效果插入、图片、文本、点击事件...。 Android 提供多种类型的 Span,其中涵盖各种常见的文本样式格式。您也可以创建自己的 Span,以应用自定义样式。详参[android.text.Span](https://developer.android.google.cn/guide/topics/text/spans?hl=zh)。 |类|可变文本|可变标记|数据结构| |-|-|-|-| |SpannedString|否|否|线性数组| |SpannableString|否|是|线性数组| |SpannableStringBuilder|是|是|区间树| 下面介绍如何决定使用哪个类: - 如果您在创建后未修改文本或标记,请使用 ==SpannedString==。 - 如果您需要将少量 Span 附加到单个文本对象,并且文本本身为只读,请使用 ==SpannableString==。 - 如果您需要在创建后修改文本,并且需要将 Span 附加到文本,请使用 ==SpannableStringBuilder==。 - 如果您需要将大量 Span 附加到文本对象,则无论文本本身是否为只读,都使用 ==SpannableStringBuilder==。 --- 应用 Span,请对 Spannable 对象调用 `setSpan(Object _what_, int _start_, int _end_, int _flags_)`。`what` 参数指的是要应用于文本的 Span,而 `start` 和 `end` 参数指的是要将该 Span 应用到的部分文本。 ```Java spannable = new SpannableStringBuilder("Text is spantastic!"); spannable.setSpan( new ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE ); ``` ![](https://developer.android.google.cn/guide/topics/text/images/spans-fg-color.png) 1. 使用 `Spannable.SPAN_EXCLUSIVE_INCLUSIVE`时,该 Span会展开以包含在 Span 边界处插入的文本; 1. 使用 `Spannable.SPAN_EXCLUSIVE_INCLUSIVE` 时, 该 Span会展开以包含其他文本。 ##### `Spanable`中的常用常量: - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE — 前后都不包括 (a,b) - Spanned.SPAN_EXCLUSIVE_INCLUSIVE — 前面不包括,后面包括 (a,b] - Spanned.SPAN_INCLUSIVE_EXCLUSIVE — 前面包括,后面不包括 [a,b) - Spanned.SPAN_INCLUSIVE_INCLUSIVE — 前后都包括 [a,b] ```java //字体(default,default-bold,monospace,serif,sans-serif) span.setSpan(new TypefaceSpan("serif"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` --- ## android.text.style Android 在 [++android.text.style++](https://developer.android.google.cn/reference/android/text/style/package-summary) 软件包中提供了超过 20 种 Span 类型。Android 以两种主要方式对 Span 进行分类 (跨度=Span) |类|说明| |-|-| |AbsoluteSizeSpan |跨度可更改附加到其上的文本的大小。 | |AlignmentSpan.Standard| 的默认实现AlignmentSpan。 | |BackgroundColorSpan |更改跨度附加到的文本的背景颜色。 | |BulletSpan| 一个将段落样式化为项目符号点的跨度(相对于布局方向)。 | |CharacterStyle| 影响字符级文本格式的类扩展了该类。 | |ClickableSpan |如果使用LinkMovementMethod的移动方法将此类型的对象附加到TextView的文本,则可以选择受影响的文本范围。 | |DrawableMarginSpan |一个跨度,在其所附加的段落中添加了一个可绘制对象和一个填充。 | |DynamicDrawableSpan| 跨度用Drawable可以与底部或周围文本的基线对齐的替换附加的文本。 | |EasyEditSpan |提供一种简单的方法来编辑部分文本。 | |ForegroundColorSpan |更改跨度附加到的文本的颜色。 | |IconMarginSpan |影响跨度的段落,在文本的开头绘制一个位图。 | |ImageSpan| 跨度用Drawable可以与底部或周围文本的基线对齐的替换附加的文本。 | |LeadingMarginSpan.Standard |LeadingMarginSpan的标准实现,该实现调整边距但不执行任何渲染。 | |LineBackgroundSpan.Standard |的默认实现LineBackgroundSpan,它会更改跨度所连接的行的背景颜色。 | |LineHeightSpan.Standard |的默认实现LineHeightSpan,它会更改所附段落的行高。 | |LocaleSpan| 更改Locale跨度附加到的文本的。 | |MaskFilterSpan |跨度允许MaskFilter对附加的文本设置a 。 | |MetricAffectingSpan |以改变字符宽度或高度的方式影响字符级文本格式的类扩展了该类。 | |QuoteSpan |一个跨度,通过在文本的开头(沿布局方向)添加垂直条纹来为段落设置样式。 | |RelativeSizeSpan |以一定比例一致地缩放附加文本的大小。 | |ReplacementSpan || |ScaleXSpan |按一定比例水平缩放其所附文本的大小。 | |StrikethroughSpan| 跨接在其附加文本上的跨度。 | |StyleSpan |跨度允许设置其附加文本的样式。 | |SubscriptSpan |使文本基线位置降低的跨度。 | |SuggestionSpan |保留此范围内文本的建议候选。 | |SuperscriptSpan |将文本基线的位置移高的跨度。 | |TabStopSpan.Standard| TabStopSpan的默认实现,该设置允许设置制表符停止位置与文本第一行的页边距的偏移量。 | |TextAppearanceSpan| 使用给定的TextAppearance属性设置文本外观 。 | |Span| 一个跨度,该跨度为打算用于文本到语音引擎的关联文本提供其他元数据。 | |TtsSpan.Builder <C扩展了 Builder <?>>|一个简单的|TtsSpans构建器。 | |TtsSpan.CardinalBuilder |TtsSpans类型的构建器。 TtsSpan.TYPE_CARDINAL| |TtsSpan.DateBuilder |TtsSpans类型的构建器。 TtsSpan.TYPE_DATE| |TtsSpan.DecimalBuilder |TtsSpans类型的构建器。 TtsSpan.TYPE_DECIMAL| |TtsSpan.DigitsBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_DIGITS| |TtsSpan.ElectronicBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_ELECTRONIC| |TtsSpan.FractionBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_FRACTION| |TtsSpan.MeasureBuilder |TtsSpans类型的构建器。 TtsSpan.TYPE_MEASURE| |TtsSpan.MoneyBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_MONEY| |TtsSpan.OrdinalBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_ORDINAL| |TtsSpan.SemioticClassBuilder<C extends SemioticClassBuilder<?>>| TtsSpans的构建器,具有用于句法特征的二传手。 | |TtsSpan.TelephoneBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_TELEPHONE| |TtsSpan.TextBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_TEXT| |TtsSpan.TimeBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_TIME| |TtsSpan.VerbatimBuilder| TtsSpans类型的构建器。 TtsSpan.TYPE_VERBATIM| |TypefaceSpan |跨度,用于更新所附加文本的字体。 | |UnderlineSpan| 跨度会突出显示其所附加的文本。 | |URLSpan |的实施ClickableSpan,允许设置一个URL字符串。 | --- > 范码 - ### 设置字体样式 ```Java span.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), 16, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //正常 span.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 18, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗体 span.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 20, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //斜体 span.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 22, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗斜体 text.append(span); ``` - ### 设置字体颜色 ```java //设置字体前景色 span.setSpan(new ForegroundColorSpan(Color.BLUE), 10, 13, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //设置字体背景色 span.setSpan(new BackgroundColorSpan(Color.GREEN), 13, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 设置字体 ```java //字体(default,default-bold,monospace,serif,sans-serif) span.setSpan(new TypefaceSpan("monospace"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new TypefaceSpan("serif"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 设置字体大小 ```js span.setSpan(new AbsoluteSizeSpan(20), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new AbsoluteSizeSpan(20,true), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new RelativeSizeSpan(2.0f), 8, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 设置下划线 ```java span.setSpan(new UnderlineSpan(), 25, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 设置删除线 ```java span.setSpan(new StrikethroughSpan(), 28, 31, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 设置上下标 ```java span.setSpan(new SuperscriptSpan(), 31, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //上标 span.setSpan(new SubscriptSpan(), 33, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下标 text.append(span); ``` - ### 设置超链接 ```java span.setSpan(new URLSpan("tel:4155551212"), 35, 40, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //电话 span.setSpan(new URLSpan("mailto:webmaster@google.com"),40, 42, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //邮件 span.setSpan(new URLSpan("http://www.baidu.com"), 42, 44, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //网络 span.setSpan(new URLSpan("sms:4155551212"), 44, 46, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //短信 使用sms:或者smsto: span.setSpan(new URLSpan("mms:4155551212"), 46, 48, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //彩信 使用mms:或者mmsto: span.setSpan(new URLSpan("geo:38.899533,-77.036476"), 48, 50, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //地图 text.append(span); ``` - ### 缩放效果 ```java span.setSpan(new ScaleXSpan(2.0f), 50, 54, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ScaleXSpan()X轴方向放大为默认字体的倍数,而高度不变;2.0f 表示默认字体宽度的两倍。 ``` - ### 修饰效果 ```java //模糊 span.setSpan(new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL)), 54, 58, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //浮雕 span.setSpan(new MaskFilterSpan(new EmbossMaskFilter({ 1, 1, 1 }, 0.4, 6, 3.5)), 58, 62, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 插入图片 ```java span.setSpan(new ImageSpan(this, @ic_launcher), 62, 66, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 文本点击事件 ```java click = new ClickableSpan() { onClick(widget) { }, updateDrawState(ds) { ds.setColor(ds.linkColor);//设置可以点击文本部分的颜色 ds.setUnderlineText(true);//设置该文本部分是否显示超链接形式的下划线 }, }; span.setSpan(click,66, 72, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); text.append(span); ``` - ### 渐变色 ```Java shader = new LinearGradient( 0, 0, 0, text.getTextSize(), Color.RED, Color.BLUE, Shader.TileMode.CLAMP); text.getPaint().setShader(shader); ```