Android SpannableStringBuilder 创建具有多种字体/文本大小等的字符串示例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10828182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SpannableStringBuilder to create String with multiple fonts/text sizes etc Example?
提问by Code Droid
I need to create a String placed in a TextView that will display a string like this:
我需要创建一个放置在 TextView 中的字符串,它将显示这样的字符串:
First Part Not Bold BOLDrest not bold
第一部分不粗体 BOLD其余部分不粗体
So I want to know how I could use SpannableStringBuilder
to do this?
所以我想知道我如何SpannableStringBuilder
才能做到这一点?
I could use three TextEdit to accomplish this but I would like to use best solution.
我可以使用三个 TextEdit 来完成此操作,但我想使用最佳解决方案。
回答by Mohammed Azharuddin Shaikh
First Part Not Bold BOLD rest not bold
You can do this either as @Rajesh suggested or by this.
您可以按照@Rajesh 的建议或通过这样做来执行此操作。
String normalBefore= "First Part Not Bold ";
String normalBOLD= "BOLD ";
String normalAfter= "rest not bold";
String finalString= normalBefore+normalBOLD+normalAfter;
Spannable sb = new SpannableString( finalString );
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size
to show this in TextView
在 TextView 中显示这个
textview.setText(sb, TextView.BufferType.SPANNABLE);
回答by Josh
The accepted answer is fine (and I upvoted it), but it fails to use the SpannableStringBuilder as the submitter requested. As I had a case where the Builder made the most sense, here is the code for that (with a bonus use of also changing the color of the text if that is helpful to others). Note that you could also provide the initial string to the SpannableStringBuilder constructor, but I set it here to use "append" to be clear that you can append a lot before your desired "bold" text and then just record the start as shown. I would suspect that this is also faster code than the accepted answer.
接受的答案很好(我赞成),但它未能按照提交者的要求使用 SpannableStringBuilder。因为我有一个 Builder 最有意义的案例,这里是代码(如果对其他人有帮助,还可以更改文本的颜色)。请注意,您还可以向 SpannableStringBuilder 构造函数提供初始字符串,但我在此处将其设置为使用“追加”,以明确您可以在所需的“粗体”文本之前追加很多内容,然后只记录开始,如图所示。我怀疑这也是比接受的答案更快的代码。
SpannableStringBuilder longDescription = new SpannableStringBuilder();
longDescription.append("First Part Not Bold ");
int start = longDescription.length();
longDescription.append("BOLD");
longDescription.setSpan(new ForegroundColorSpan(0xFFCC5500), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.append(" rest not bold");
回答by Gober
From API 21 SpannableStringBuilder includes a simple method to do this. Here is a solution example:
从 API 21 SpannableStringBuilder 包含一个简单的方法来做到这一点。这是一个解决方案示例:
SpannableStringBuilder builder= new SpannableStringBuilder();
StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
builder.append("First Part Not Bold ")
.append("BOLD ", boldSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
.append("rest not bold");
Since it is a good chance you do not support API 21 only you can duplicate the code from that method:
由于您很可能不支持 API 21,因此您可以从该方法中复制代码:
public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
int start = length();
append(text);
setSpan(what, start, length(), flags);
return this;
}
回答by David Rawson
If you are using Kotlin you can do the following using the android-ktxlibrary
如果您使用的是 Kotlin,则可以使用android-ktx库执行以下操作
val s = SpannableStringBuilder()
.append("First Part Not Bold ")
.bold { append("BOLD") }
.append("Rest not bold")
The bold
is an extension function on SpannableStringBuilder
. You can see the documentation herefor a list of operations you can use.
该bold
是一个扩展功能SpannableStringBuilder
。您可以在此处查看文档,了解您可以使用的操作列表。
Another example:
另一个例子:
val s = SpannableStringBuilder()
.color(green, { append("Green text ") })
.append("Normal text ")
.scale(0.5, { append("Text at half size " })
.backgroundColor(green, { append("Background green") })
Where green
is a resolved RGB color.
哪里green
是已解析的 RGB 颜色。
It is even possible to nest spans so you end up with an embedded DSL:
甚至可以嵌套跨度,因此您最终会得到一个嵌入式 DSL:
bold { underline { italic { append("Bold and underlined") } } }
You will need the following in your app module level build.gradle
for it to work:
您的应用程序模块级别需要以下内容build.gradle
才能使其工作:
repositories {
google()
}
dependencies {
implementation "androidx.core:core-ktx:1.2.0"
}
回答by live-love
This code should set to bold everything that comes inside the html bold tag. And it also deletes the tag so only the content inside is displayed.
此代码应设置为粗体显示 html 粗体标签内的所有内容。它还会删除标签,因此只显示里面的内容。
SpannableStringBuilder sb = new SpannableStringBuilder("this is <b>bold</b> and this is <b>bold too</b> and this is <b>bold too, again</b>.");
Pattern p = Pattern.compile("<b>.*?</b>", Pattern.CASE_INSENSITIVE);
boolean stop = false;
while (!stop)
{
Matcher m = p.matcher(sb.toString());
if (m.find()) {
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.delete(m.end()-4, m.end());
sb.delete(m.start(), m.start() + 3);
}
else
stop = true;
}
This code can also be adapted for other html style tags, such as Superscript (sup tag), etc.
这段代码也可以适配其他html样式的标签,比如Superscript(sup标签)等。
SpannableStringBuilder sb = new SpannableStringBuilder("text has <sup>superscript</sup> tag");
Pattern p = Pattern.compile("<sup>.*?</sup>", Pattern.CASE_INSENSITIVE);
boolean stop = false;
while (!stop)
{
Matcher m = p.matcher(sb.toString());
if (m.find()) {
sb.setSpan(new SuperscriptSpan(), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.delete(m.end()-6, m.end());
sb.delete(m.start(), m.start() + 5);
}
else
stop = true;
}
To set the color, just use the ForegroundColorSpan with setSpan.
要设置颜色,只需使用 ForegroundColorSpan 和 setSpan。
sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Hope it helps.
希望能帮助到你。
回答by Rajesh
回答by Zeppie
So I know this has been solved, and even as requested with SpannableStringBuilder but in the event you wanted to build a string more dynamically I figured I would put this up.
所以我知道这已经解决了,即使按照 SpannableStringBuilder 的要求,但如果您想更动态地构建字符串,我想我会提出来。
// Stuff needed
TextView DataTextView = (TextView)rootView.findViewById(R.id.DataView);
String Fields[] = {...database column names as strings... "x","y"};
String DataString = new String();
int start,stop; // Start and Stop of formatting
// Final Result
SpannableStringBuilder coloredString = new SpannableStringBuilder();
SpannableString temp; // Small segment of colored string
for (int i =0; i < Fields.length; i++)
{
if (database_result.containsKey(Fields[i])) // Be sure a field exists in the ContentValues
{
DataString = Fields[i]+": ";
start = DataString.length();
DataString = DataString+ +database_result.getAsInteger(Fields[i])+" ";
stop= DataString.length();
temp = new SpannableString(DataString);
temp.setSpan(new ForegroundColorSpan(Color.WHITE),start, stop, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
coloredString.append(temp);
}
}
DataTextView.setText(coloredString);
database_result is a ContentValues type that I constructed from the returned Cursor type of the SQL query. The only problem I had with this was at first it was only ColorSpaning the first segment. It seams that you need to declare a new ForegroundColorSpan every time you want to use one (or any other kind of span) in a loop.
database_result 是我从 SQL 查询返回的 Cursor 类型构造的 ContentValues 类型。我遇到的唯一问题是起初它只是 ColorSpaning 的第一部分。每次您想在循环中使用一个(或任何其他类型的跨度)时,您都需要声明一个新的 ForegroundColorSpan。
回答by Mahendran Sakkarai
We can also use SpannableStringBuilderwith TextAppearanceSpanto accomplish that. Follow the below steps to implement like that.
我们还可以将SpannableStringBuilder与TextAppearanceSpan一起使用来实现这一点。按照以下步骤来实现。
- Create a style in
styles.xml
.
- 中创建样式
styles.xml
。
<style name="BoldStyle">
<!-- Can add other styling attributes -->
<item name="android:textStyle">bold</item>
......
</style>
- Use the below code.
- 使用下面的代码。
SpannableStringBuilder builder = new SpannableStringBuilder("First Part Not Bold BOLD rest not bold"); builder.setSpan(new TextAppearanceSpan(this, R.style.BoldStyle), 20, 24, 0); ((TextView)findViewById(R.id.tv7)).setText(builder);
That's it. Hope it'll help someone.
就是这样。希望它会帮助某人。
回答by qtyq
Why would you use SpannableStringBuilder when you can use SpannableBuilder?? (https://gist.github.com/qtyq/90f9b4894069a8b3676c)
当您可以使用 SpannableBuilder 时,为什么还要使用 SpannableStringBuilder?( https://gist.github.com/qtyq/90f9b4894069a8b3676c)
SpannableString ss = SpannableBuilder.init("First Part Not Bold BOLD rest not bold")
.makeBold("BOLD")
.create()