文字格式化 (Spannable)
在 Android 开发中,Spannable 是一种用于对文本进行格式化的强大工具。它允许你对文本的不同部分应用不同的样式,而不仅仅是对整个 TextView 应用样式。这种方式对于处理复杂的文本排版和样式非常有用。
创建和使用 Spannable
首先,你需要创建一个 Spannable 实例。Spannable 实际上是一个接口,而 SpannableString 和 SpannableStringBuilder 是它的两个常用实现。如果你的文本内容会修改,建议使用 SpannableStringBuilder。
java
// 创建一个 SpannableString 实例
Spannable spannable = new SpannableString("some content");
// 或者使用 SpannableStringBuilder 实例(如果你会修改内容)
SpannableStringBuilder spannableBuilder = new SpannableStringBuilder("some content");应用样式
你可以使用 setSpan 方法在 Spannable 中指定不同的样式。setSpan 方法需要四个参数:
Object what: 要应用的样式对象,比如ForegroundColorSpan。int start: 起始索引,样式应用的开始位置。int end: 结束索引,样式应用的结束位置。int flags: 标记,指定如何处理相邻的样式。常用的标记有:Spanned.SPAN_EXCLUSIVE_EXCLUSIVESpanned.SPAN_INCLUSIVE_EXCLUSIVESpanned.SPAN_EXCLUSIVE_INCLUSIVESpanned.SPAN_INCLUSIVE_INCLUSIVE
常用的 Span 实现
以下是一些常见的 Span 实现:
ForegroundColorSpan: 设置前景颜色(文本颜色)。spannable.setSpan(new ForegroundColorSpan(0xfff699b4), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);RelativeSizeSpan: 设置字体大小比例。spannable.setSpan(new RelativeSizeSpan(1.5f), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);StyleSpan: 设置字体样式,如粗体或斜体。spannable.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);URLSpan: 设置超链接。spannable.setSpan(new URLSpan("http://example.com"), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);UnderlineSpan: 添加下划线。spannable.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);StrikethroughSpan: 添加删除线。spannable.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
一个字符可以同时应用多种 Span,例如同时应用颜色和下划线:
java
public void configureSpan() {
spannable.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}设置预排版
在将 Spannable 应用到 TextView 时,可以使用预排版来提高性能。预排版会计算文本的排版信息,从而减少文本渲染时的计算开销。
java
public void someMethod() {
// 创建 SpannableStringBuilder 实例并设置样式
SpannableStringBuilder spannable = new SpannableStringBuilder("some content");
spannable.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 创建预排版文本并设置给 TextView
CompletableFuture.runAsync(() -> {
// 获取 TextView 的 TextMetricsParams
TextView tv = getView();//从某处获取TextView
var precomputed = PrecomputedText.create(spannable, tv.getTextMetricsParams());
// 在主线程中设置预排版文本
tv.post(() -> tv.setText(precomputed, TextView.BufferType.SPANNABLE));
});
}在这段代码的逻辑是:
- 创建
SpannableStringBuilder实例,并设置相应的样式,这里是将索引为1到3(首尾均被排除)的字设置为红色 - 使用
PrecomputedText.create()方法创建预排版文本。 - 使用
TextView.post()方法将预排版文本设置到TextView中,以保证在主线程中更新 UI。
配置后,TextView 将能够正确处理和显示预排版的文本内容。