如何在TextView BOLD上制作特定文本

Bud*_*wan 216 android textview android-textattributes

我不知道如何使TextView上的特定文本变为BOLD.

就像这样

txtResult.setText(id+" "+name);
Run Code Online (Sandbox Code Playgroud)

我希望输出如下:

1111尼尔

id并且name是我从数据库中检索了值的变量,我想使其id变为粗体,但只有id这样才name不会受到影响,我不知道如何做到这一点.

wts*_*g02 357

虽然你可以使用Html.fromHtml(),你可以使用更原生的方法,即SpannableStringBuilder,这篇文章可能很有用.

SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text");
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), INT_START, INT_END, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv=new TextView(context);
tv.setText(str);
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要本地化您的副本,这将完全中断. (22认同)
  • 对于来自Google且没有任何先验知识的人:INT_START/INT_END是粗体应该开始和结束的位置. (8认同)
  • 在有疑问时尝试理解代码正在做什么.int start是您定义的数字,它是范围的起始索引.尝试0表示开始,字符串.().size()表示结束. (4认同)
  • 如果只需要对源字符串应用一些标记而不更改它,那么最好使用SpannableString类 (2认同)

Rag*_*ood 343

只需在HTML中构建String并设置它:

String sourceString = "<b>" + id + "</b> " + name; 
mytextview.setText(Html.fromHtml(sourceString));
Run Code Online (Sandbox Code Playgroud)

  • 这会降低性能.使用@ wtsang02解决方案 (34认同)
  • 由于在HTML 24中不推荐使用fromHtml(sourceString),因此必须使用下一个代码:Spanned durationSpanned; 如果(android.os.Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.N){durationSpanned = Html.fromHtml(durationFormatted,Html.FROM_HTML_MODE_LEGACY); } else {durationSpanned = Html.fromHtml(durationFormatted); } (4认同)
  • `Html.fromHtml()`现已弃用 (4认同)
  • 您可以使用 text.text = HtmlCompat.fromHtml( ctx.getString(R.string.logout_confirm), HtmlCompat.FROM_HTML_MODE_COMPACT ) (4认同)
  • 如果要本地化应用程序,这是唯一可行的选项。 (2认同)

Fil*_*ito 62

首先:您不必担心使用Raghav Sood的答案中的慢性能代码.

第二:使用Kotlin时,您不需要编写w3bshark答案提供的扩展功能.

Finnaly:你需要做的就是使用谷歌的Kotlin android-ktx库:

// Suppose id = 1111 and name = neil (just what you want). 
val s = SpannableStringBuilder()
          .bold { append(id) } 
          .append(name)
txtResult.setText(s) 
Run Code Online (Sandbox Code Playgroud)

产生:1111尼尔


更新:

因为我认为它可以帮助其他人以及展示你可以走多远这里有更多的用例.

  • 当您需要显示包含蓝色和斜体的某些部分的文本时:

    val myCustomizedString = SpannableStringBuilder()
        .color(blueColor, { append("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
    
    Run Code Online (Sandbox Code Playgroud)
  • 当您需要以粗体和斜体显示文本时:

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

总之,bold,append,coloritalic在扩展功能SpannableStringBuilder.您可以在官方文档中看到其他扩展功能,您可以从中考虑其他可能性.

  • 为这个现代解决方案和资源的家伙授予一枚奖章!谢谢!!! (9认同)
  • 这很棒,但我认为与字符串相关的每个答案都应该考虑翻译。在某些语言中,句子中的单词的排序和结构可能完全不同,因此像这样的附加并不总是适用于某些情况。对于 XML 中的数量字符串之类的内容也不是理想的选择。 (2认同)
  • @CoolMind 它不会让你无法使用 Android KTX。您可以从 github.com/android/android-ktx 找到有关如何报告错误、提出功能建议或为该库做出贡献的信息。所以,它仍然是一个有效的参考。我已经更新了我的答案,以包含有关该库以及如何在您的项目中使用它的更多信息。 (2认同)

小智 36

我认为所选择的答案没有提供令人满意的结果.我写了自己的函数,需要2个字符串; 全文和要加粗的文本部分.

它返回一个SpannableStringBuilder,其中'textToBold'来自'text'粗体.

我发现能够将子字符串加粗而不将其包装在有用的标签中.

    /**
     * Makes a substring of a string bold.
     * @param text          Full text
     * @param textToBold    Text you want to make bold
     * @return              String with bold substring
     */

    public static SpannableStringBuilder makeSectionOfTextBold(String text, String textToBold){

        SpannableStringBuilder builder=new SpannableStringBuilder();

        if(textToBold.length() > 0 && !textToBold.trim().equals("")){

            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textToBold.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();
            //for counting start/end indexes

            if(startingIndex < 0 || endingIndex <0){
                return builder.append(text);
            }
            else if(startingIndex >= 0 && endingIndex >=0){

                builder.append(text);
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }else{
            return builder.append(text);
        }

        return builder;
  }
Run Code Online (Sandbox Code Playgroud)

  • @MicroR你需要传递两个字符串,第二个字符串需要是第一个包含的文本部分.例如makeSectionOfTextBold("这是一些很棒的文字.","很棒"). (2认同)
  • 此函数不期望子字符串可以多次出现在全文中.例如,在"我的用户名是名称"中,它不能使第二个"名称"加粗. (2认同)

Jad*_*mec 24

正如wtsang02所说,使用HTML是一种昂贵的开销.只需使用本机解决方案.如果您不必修改字符串,只需使用SpannableString,而不是SpannableStringBuilder.

String boldText = "id";
String normalText = "name";
SpannableString str = new SpannableString(boldText + normalText);
str.setSpan(new StyleSpan(Typeface.BOLD), 0, boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(str);
Run Code Online (Sandbox Code Playgroud)


and*_*per 15

如果您想使用XML中的字符串,您可以执行以下操作:

strings.xml中

<string name="test">
     <![CDATA[
 <b>bold!</b> normal
    ]]>
</string>
Run Code Online (Sandbox Code Playgroud)

码:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)


Rid*_*zag 11

它只是简单地关闭指定的文本,例如 <b>"your text here:"</b>

<string name="headquarters">"<b>"Headquarters:"</b>" Mooresville, North Carolina, U.S.</string>
Run Code Online (Sandbox Code Playgroud)

结果: 总部:美国北卡罗来纳州穆尔斯维尔

  • 仅当使用 xml 中的字符串时,此方法才有效。如果以编程方式调用此字符串,则 html 编码将被删除。 (4认同)

Kri*_*hna 10

如果您想将多个文本设置为粗体,这是更好的解决方案.我改进了Eitan的代码.谢谢Eitan.

public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) {
    SpannableStringBuilder builder = new SpannableStringBuilder(text);

    for (String textItem :
            textToBold) {
        if (textItem.length() > 0 && !textItem.trim().equals("")) {
            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textItem.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();

            if (startingIndex >= 0 && endingIndex >= 0) {
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }
    }

    return builder;
}
Run Code Online (Sandbox Code Playgroud)


liv*_*ove 7

您可以使用此代码将部分文本设置为粗体。对于粗体 html 标记之间的任何内容,它将使其变为粗体。

String myText = "make this <b>bold</b> and <b>this</b> too";
textView.setText(makeSpannable(myText, "<b>(.+?)</b>", "<b>", "</b>"));

public SpannableStringBuilder makeSpannable(String text, String regex, String startTag, String endTag) {

            StringBuffer sb = new StringBuffer();
            SpannableStringBuilder spannable = new SpannableStringBuilder();

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
                sb.setLength(0);
                String group = matcher.group();
                String spanText = group.substring(startTag.length(), group.length() - endTag.length());
                matcher.appendReplacement(sb, spanText);

                spannable.append(sb.toString());
                int start = spannable.length() - spanText.length();

                spannable.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            sb.setLength(0);
            matcher.appendTail(sb);
            spannable.append(sb.toString());
            return spannable;
        }
Run Code Online (Sandbox Code Playgroud)


Yus*_*f X 6

根据@ mladj0ni的回答,我得到了下面的代码.问题是,如果你使用String.format,它会删除html标记,所以你必须转义strings.xml中的括号符号:

strings.xml中:

<string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>

code.java:

String unspanned = String.format(Locale.US, "%s%s", getResources().getString(R.string. welcome_messages), 99);

Spanned spanned;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    spanned = Html.fromHtml(unspanned, Html.FROM_HTML_MODE_LEGACY);
} else {
    spanned = Html.fromHtml(unspanned);
}

textView.setText(spanned);
Run Code Online (Sandbox Code Playgroud)

它比SpannableStringBuilder更简单.至于性能,如果你只显示一个字符串,那么用户将不会注意到额外的毫秒来解析它.

请参阅此处的文档.


Dev*_*rya 6

如果您使用的是Kotlin,则可以通过使用来变得更加容易core-ktx,因为它提供了一种特定域的语言(DSL)

val string: SpannedString = buildSpannedString {
    bold {
        append("1111")
    }
    append("neil)     
}
Run Code Online (Sandbox Code Playgroud)

它提供的更多选项是:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以执行以下操作:

textView.text = string
Run Code Online (Sandbox Code Playgroud)


Jun*_*ana 5

wtsang02答案是最好的方法,因为 Html.fromHtml("") 现在已被弃用。在这里,无论句子的大小如何,我都会为在动态使第一个单词加粗时遇到问题的人稍微增强它。

首先让我们创建一个方法来获取第一个单词:

 private String getFirstWord(String input){

    for(int i = 0; i < input.length(); i++){

        if(input.charAt(i) == ' '){

            return input.substring(0, i);
        }
    }

    return input;
}
Run Code Online (Sandbox Code Playgroud)

现在假设你有一个像这样的长字符串:

String sentence = "friendsAwesomeName@gmail.com want's to be your friend!"
Run Code Online (Sandbox Code Playgroud)

你希望你的句子像yourAwesomeName@gmail.com想要成为你的朋友!你所要做的就是 - 获取 firstWord 并获取它的长度以使 firstWord 加粗,如下所示:

String myFirstWord = getFirstWord(sentence);
int start = 0; // bold will start at index 0
int end = myFirstWord.length(); // and will finish at whatever the length of your first word
Run Code Online (Sandbox Code Playgroud)

现在只需按照wtsang02 的步骤,像这样:

SpannableStringBuilder fancySentence = new SpannableStringBuilder(sentence);
fancySentence.setSpan(new android.text.style.StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(fancySentence);
Run Code Online (Sandbox Code Playgroud)

就是这样!现在,您应该能够将长句/短句中任意大小的单词加粗。希望它会帮助某人,快乐编码:)


AI *_*kil 5

这段代码不是最简单的解决方案吗?

<string name="string">Please provide your <b>Name</b> properly</string>
Run Code Online (Sandbox Code Playgroud)

只要你想用这个字符串就可以了:)

结果会是这样的:

请正确提供您的姓名

  • 仅当我们在 XML 上设置字符串资源时,此解决方案才有效。比如: &lt;TextView ... ... android:text="@string/string" /&gt; 但当我们以编程方式设置字符串资源时,它失败了。如:textView.text = resources.getString(R.string.string) (8认同)