SpannableStringBuilder创建具有多个字体/文本大小的String等示例?

Cod*_*oid 70 android spannablestring spannablestringbuilder

我需要创建一个放在TextView中的String,它将显示如下字符串:

第一部分不大胆 大胆 休息不大胆

所以我想知道如何使用它SpannableStringBuilder来做到这一点?

我可以使用三个TextEdit来完成这个,但我想使用最佳解决方案.

Moh*_*ikh 74

First Part Not Bold   BOLD  rest not bold
Run Code Online (Sandbox Code Playgroud)

你可以像@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
Run Code Online (Sandbox Code Playgroud)

在TextView中显示

textview.setText(sb,  TextView.BufferType.SPANNABLE);
Run Code Online (Sandbox Code Playgroud)

  • 另请更新索引为(finalString.indexOf(normalBOLD),finalString.indexOf(normalBOLD)+ normalBOLD.lenth()) (7认同)
  • 除了CodeDroid所说的,另一个问题是indexOf方法可以捕获重复的单词并在`start`之前将`end`留给`IndexOutOfBoundsException`.所以最好格式化子串然后将它们组合在一起. (2认同)

Jos*_*osh 72

接受的答案很好(我赞成它),但它没有使用SpannableStringBuilder作为提交者请求.由于我有一个Builder最有意义的情况,这里是代码(如果对其他人有帮助,还可以使用也改变文本的颜色).请注意,您还可以向SpannableStringBuilder构造函数提供初始字符串,但我在此处将其设置为使用"append"清楚地表明您可以在所需的"粗体"文本之前附加很多内容,然后只记录开头,如图所示.我怀疑这也是比接受的答案更快的代码.

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");
Run Code Online (Sandbox Code Playgroud)

  • 此外,通过在附加文本之前检索文本粗体部分的开始位置,您不必担心应该是粗体的单词的重复出现. (2认同)

Gob*_*ber 36

从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");
Run Code Online (Sandbox Code Playgroud)

由于您很可能不支持API 21,因此您可以复制该方法中的代码:

public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
        int start = length();
        append(text);
        setSpan(what, start, length(), flags);
        return this;
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 17

如果您使用的是Kotlin,则可以使用android-ktx库执行以下操作

val s = SpannableStringBuilder()
        .append("First Part Not Bold ")
        .bold { append("BOLD") } 
        .append("Rest not bold")
Run Code Online (Sandbox Code Playgroud)

bold是一个扩展功能SpannableStringBuilder。您可以在此处查看文档以获取可以使用的操作列表。

另一个例子:

val s = SpannableStringBuilder()
            .color(green, { append("Green text ") })
            .append("Normal text ")
            .scale(0.5, { append("Text at half size " })
            .backgroundColor(green, { append("Background green") })
Run Code Online (Sandbox Code Playgroud)

green解析的RGB颜色在哪里。

甚至有可能嵌套跨度,因此您最终会获得嵌入式DSL:

bold { underline { italic { append("Bold and underlined") } } }
Run Code Online (Sandbox Code Playgroud)

您需要在您的应用程序模块级别中执行build.gradle以下操作才能使其正常工作:

repositories {
    google()
}

dependencies {
    implementation 'androidx.core:core-ktx:0.3'
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你会使用 Kotlin,这绝对是最好的选择。DSL 使其成为一个非常非常好的 API。 (4认同)
  • 它如何与 LiveData<String> 一起使用?即使一切都在编译并且看起来没问题,我似乎无法让它应用这些更改? (2认同)

Raj*_*esh 6

使用Html类在TextView中使用HTML代码:

Spanned styledText = Html.fromHtml("First Part Not Bold <b>BOLD</b> rest not bold");
textView.setText(styledText);
Run Code Online (Sandbox Code Playgroud)

  • 请记住,这非常慢,如果在滚动期间完成,可能会导致跳过帧. (18认同)

liv*_*ove 5

这段代码应将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;
        }
Run Code Online (Sandbox Code Playgroud)

此代码也可以适用于其他html样式标签,例如上标(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;
        }
Run Code Online (Sandbox Code Playgroud)

要设置颜色,只需将ForegroundColorSpan与setSpan一起使用。

sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。


Mah*_*rai 5

我们还可以将SpannableStringBuilderTextAppearanceSpan一起使用来实现这一点。按照以下步骤来实现。

  1. 中创建样式styles.xml

<style name="BoldStyle">
   <!-- Can add other styling attributes -->
   <item name="android:textStyle">bold</item>
   ......
</style>
Run Code Online (Sandbox Code Playgroud)

  1. 使用下面的代码。
SpannableStringBuilder builder = new SpannableStringBuilder("第一部分不粗体粗体其余不粗体");
builder.setSpan(new TextAppearanceSpan(this, R.style.BoldStyle), 20, 24, 0);
((TextView)findViewById(R.id.tv7)).setText(builder);

就是这样。希望它会帮助某人。


Rez*_*reh 5

您可以在 kotlin 中将字符串的一部分加粗并调整其大小

val s = SpannableStringBuilder()
    .append("First Part Not Bold And No Resize ")
    .bold { scale(1.5f, { append("Second Part By Bold And Resize " )}) } 
    .append("Third Part Not Bold And No Resize")

yourTextview.text = s
Run Code Online (Sandbox Code Playgroud)