是否可以为TextView中的不同文本设置多个样式?
例如,我将文本设置如下:
tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3);
Run Code Online (Sandbox Code Playgroud)
是否可以为每个文本元素设置不同的样式?例如,line1粗体,word1斜体等.
开发人员指南的常见任务和Android中的操作方法包括选择,突出显示或设置部分文本样式:
Run Code Online (Sandbox Code Playgroud)// Get our EditText object. EditText vw = (EditText)findViewById(R.id.text); // Set the EditText's text. vw.setText("Italic, highlighted, bold."); // If this were just a TextView, we could do: // vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE); // to force it to use Spannable storage so styles can be attached. // Or we could specify that in the XML. // …
是否可以在TextView中设置文本范围的颜色?
我想做一些类似于Twitter应用程序的东西,其中一部分文本是蓝色的.见下图:

Android提供了多种接口所有文字和字符串相关的:
Spanned,SpannedString,Spannable,SpannableString和CharSequence.
我已经在各种场景中使用了上述所有内容,通常是在使用Html.fromHtml()内部显示可链接文本之后TextView,以便为其应用一些样式.
我试图从Android的官方文档中了解这些接口的用途/用法并且因为它很混乱而失败了.这些接口的目的是什么?在哪些情况下使用它们最常见?在哪些情况下最好避免使用它们?使用其中任何一个时,是否有任何明显的性能影响?
如果有人能提供一个体面的解释,我将不胜感激.
我想画SpannedString一个Canvas.
SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 1, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
Run Code Online (Sandbox Code Playgroud)
上面的例子是使用a绘制的TextView,而a又使用a Layout来绘制带有跨度的文本.我知道使用a Layout是向画布绘制文本的推荐方法.但是,我从头开始制作自己的文本布局,所以我需要自己实现.
做这样的事情是行不通的
canvas.drawText(spannableString, 0, spannableString.length(), 0, 0, mTextPaint);
Run Code Online (Sandbox Code Playgroud)
因为drawText只从中获取文本spannableString,而不是任何跨度.绘图颜色分别处理TextPaint.
如何使用canvas.drawText(或drawTextRun)绘制跨度信息(特别是前景和背景颜色)?
有关
计划解决方案
我打算直接做一个自我回答,但事实证明这比我想象的更难.所以我会先发帖,然后在我弄清楚的时候添加一个答案.(我当然欢迎任何人先回答.)
这是我到目前为止的作品:
drawTextRun绘制文本(例子)(更新:未添加至API 23)getRunAdvance测量从哪里开始的下一个文本运行( …我使用以下代码筛选跨区字符串,将所有粗体文本保存为数组中的字符串:
StyleSpan[] spans = storyText.getSpans(0,
storyText.length(), StyleSpan.class);
List<String> boldedWords = new ArrayList<String>();
for (StyleSpan span : spans) {
if (span.getStyle() == Typeface.BOLD) {
//start
int s = storyText
.getSpanStart(span);
//end
int e = storyText.getSpanEnd(span);
boldedWords.add(storyText.subSequence(
s, e).toString());
}
}
String[] array = boldedWords
.toArray(new String[boldedWords.size()]);
Run Code Online (Sandbox Code Playgroud)
但是,我在数组中收到的字符串是乱序的。例如:
句子可能是(大写代表粗体文本):
storyText = "This ADJECTIVE NOUN is VERB"
Run Code Online (Sandbox Code Playgroud)
我要返回的数组是:按“名词、动词、形容词”的顺序排列。应该是:“形容词,名词,动词”
关于为什么会发生这种情况的任何见解?
我想在 a 中获取一种类型的所有跨度CharSequence并将它们转换为不同的类型。例如,将所有粗体跨度转换为下划线跨度:
我该怎么做?
(这是我今天面临的一个问题,既然我现在已经解决了,我在这里添加一个问答对。我的答案如下。)