我不知道如何使TextView上的特定文本变成粗体。

是这样的

txtResult.setText(id+" "+name);

我希望输出是这样的:

1111年尼尔

id和名称是我从数据库中检索值的变量,我想将id改为粗体,但只有id,所以名称不会受到影响,我不知道如何做到这一点。


当前回答

首先:你不需要担心从Raghav Sood的答案使用缓慢的性能代码。

第二:使用Kotlin时,不需要编写w3bshark的答案提供的扩展函数。

最后:所有你需要做的就是从谷歌使用Kotlin android-ktx库(参考这里找到更多信息以及如何将它包含在你的项目中):

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

产量:1111尼尔


更新:

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

当你需要用蓝色和斜体显示文本时: val myCustomizedString = SpannableStringBuilder() .color(blueColor, {append(“蓝色文本”)}) .append("显示") .italic{append(“这是无痛的”)} 当你需要同时以粗体和斜体显示文本时: 粗体{斜体{追加(“粗体和斜体”)}}

简而言之,粗体、追加、颜色和斜体是SpannableStringBuilder的扩展函数。您可以在官方文档中看到其他扩展函数,从那里您可以考虑其他可能性。

其他回答

这里有一个更好的解决方案,如果你想使多个文本粗体。我改进了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;
}

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

它返回一个SpannableStringBuilder,带有从'text'中粗体的'textToBold'。

我发现使子字符串加粗而不用标签包装的能力很有用。

    /**
     * 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;
  }

我用这个代码来加粗特定的单词…

    Spanned string = Html.fromHtml("Normal string <b>BOLD STRING</b>");
    textView.setText(string);

根据@mladj0ni的回答,我得到了下面的代码。问题是如果你使用String。格式,它剥离了HTML标记,所以你必须转义strings.xml中的括号符号:

strings.xml:

<string name="welcome_messages">Hello, %1$s!你有&lt;b>%2$d新消息&lt;/b>.</string> .</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);

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

请在这里查看文档。

这是我使用的Kotlin扩展函数

/**
 * Sets the specified Typeface Style on the first instance of the specified substring(s)
 * @param one or more [Pair] of [String] and [Typeface] style (e.g. BOLD, ITALIC, etc.)
 */
fun TextView.setSubstringTypeface(vararg textsToStyle: Pair<String, Int>) {
    val spannableString = SpannableString(this.text)
    for (textToStyle in textsToStyle) {
        val startIndex = this.text.toString().indexOf(textToStyle.first)
        val endIndex = startIndex + textToStyle.first.length

        if (startIndex >= 0) {
            spannableString.setSpan(
                StyleSpan(textToStyle.second),
                startIndex,
                endIndex,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
    }
    this.setText(spannableString, TextView.BufferType.SPANNABLE)
}

用法:

text_view.text="something bold"
text_view.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    )
)

.

text_view.text="something bold something italic"
text_view.setSubstringTypeface(
    Pair(
        "something bold ",
        Typeface.BOLD
    ),
    Pair(
        "something italic",
        Typeface.ITALIC
    )
)