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

是这样的

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

我希望输出是这样的:

1111年尼尔

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


当前回答

找到了一种方法,如果你想处理多种语言的本地化,这很无聊,但它是有效的,让我们假设我们想要这样:

英文:

没有付款记录

西班牙语:

没有付款记录

你必须创建3个字符串

中文:

<string name="start_string">There are no</string>
<string name="middle_string">payments</string>
<string name="end_string">registered.</string>
<string name="string_format" translatable="false">%1$s %2$s %3$s</string>

西班牙语:

<string name="start_string">No hay</string>
<string name="middle_string">pagos</string>
<string name="end_string">registrados</string>

现在你可以这样做:

val startSpanPosition = getString(R.string.start_string).length
val endSpanPosition = startSpanPosition + getString(R.string.middle_string).length
val mySpannableString = SpannableStringBuilder(String.format(getString(R.string.string_format),
        getString(R.string.start_string), getString(R.string.middle_string))), getString(R.string.end_string)))

mySpannableString.setSpan(StyleSpan(Typeface.BOLD), spanStartPosition, endSpanPosition, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

其他回答

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

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

这是我的完整的解决方案,动态字符串值与大小写检查。

/**
 * Makes a portion of String formatted in BOLD.
 *
 * @param completeString       String from which a portion needs to be extracted and formatted.<br> eg. I am BOLD.
 * @param targetStringToFormat Target String value to format. <br>eg. BOLD
 * @param matchCase Match by target character case or not. If true, BOLD != bold
 * @return A string with a portion formatted in BOLD. <br> I am <b>BOLD</b>.
 */
public static SpannableStringBuilder formatAStringPortionInBold(String completeString, String targetStringToFormat, boolean matchCase) {
    //Null complete string return empty
    if (TextUtils.isEmpty(completeString)) {
        return new SpannableStringBuilder("");
    }

    SpannableStringBuilder str = new SpannableStringBuilder(completeString);
    int start_index = 0;

    //if matchCase is true, match exact string
    if (matchCase) {
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.contains(targetStringToFormat)) {
            return str;
        }

        start_index = str.toString().indexOf(targetStringToFormat);
    } else {
        //else find in lower cases
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.toLowerCase().contains(targetStringToFormat.toLowerCase())) {
            return str;
        }

        start_index = str.toString().toLowerCase().indexOf(targetStringToFormat.toLowerCase());
    }

    int end_index = start_index + targetStringToFormat.length();
    str.setSpan(new StyleSpan(BOLD), start_index, end_index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return str;
}

如。completeString = "I am BOLD"

情况下,我 if *targetStringToFormat* = "bold" and *matchCase* = true

返回“I am BOLD”(因为BOLD != BOLD)

案例二世 if *targetStringToFormat* = "bold" and *matchCase* = false

返回“I am BOLD”

应用:

myTextView.setText(formatAStringPortionInBold("I am BOLD", "bold", false))

希望有帮助!

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

它返回一个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;
  }

根据@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,使用core-ktx会变得更容易,因为它提供了一种领域特定语言(DSL)来做这件事:

val string: SpannedString = buildSpannedString {
    bold {
        append("foo")
    }
    append("bar")     
}

它提供的更多选项有:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

最后,你只需:

textView.text = string