Как сделать конкретный текст в TextView BOLD

Я не знаю, как сделать конкретный текст в TextView, становясь BOLD.

как это

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

Я хочу, чтобы результат был таким:

1111 neil

id и name - это переменные, которые я получил из базы данных, и хочу сделать id полужирным, но только id, поэтому name не повлияет, у меня есть не знаю, как это сделать.

Ответ 1

Просто создайте строку в HTML и установите ее:

String sourceString = "<b>" + id + "</b> " + name; 
mytextview.setText(Html.fromHtml(sourceString));

Ответ 2

В то время как вы можете использовать Html.fromHtml(), вы можете использовать более собственный подход, который SpannableStringBuilder, этот пост может быть helful.

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);

Ответ 3

Во-первых: вам не нужно беспокоиться об использовании медленного кода из ответа Рагхав-Суда.

Второе: вам не нужно писать функцию расширения, предоставляемую ответом w3bshark при использовании Kotlin.

Finnaly: все, что вам нужно сделать, это использовать библиотеку Kotlin android-ktx от Google:

// 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("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
    
  • Когда вам нужно отобразить текст жирным шрифтом и курсивом:

        bold { italic { append("Bold and italic") } }
    

Короче говоря, bold, append, color и italic являются функциями расширения SpannableStringBuilder. Вы можете увидеть другие функции расширения в официальной документации, откуда вы можете подумать о других возможностях.

Ответ 4

Я думал, что выбранный ответ не дал удовлетворительного результата. Я написал свою собственную функцию, которая занимает 2 строки; Полный текст и часть текста, который вы хотите сделать жирным.

Он возвращает SpannableStringBuilder с текстом 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;
  }

Ответ 5

Как сказал 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);

Ответ 6

Если вы хотите использовать строку из XML, вы можете сделать что-то вроде этого:

strings.xml

<string name="test">
     <![CDATA[
 <b>bold!</b> normal
    ]]>
</string>

код:

textView.setText(Html.fromHtml(getString(R.string.test)));

Ответ 7

Вот лучшее решение, если вы хотите сделать многократный текст полужирным. Я улучшил код 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;
}

Ответ 8

Простое просто закрыть указанный текст, например, <b>"your text here:"</b>

<string name="headquarters">"<b>"Headquarters:"</b>" Mooresville, North Carolina, U.S.</string>

Результат: Штаб-квартира: Муресвилль, Северная Каролина, США

Ответ 9

Основываясь на ответе @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);

Это проще, чем SpannableStringBuilder. Что касается производительности, если вы отображаете только одну строку, то пользователь не заметит лишнюю миллисекунду для ее анализа.

Смотрите документацию здесь.

Ответ 10

Если вы используете Kotlin, это становится еще проще сделать с помощью core-ktx, так как он предоставляет домен-специфический язык (DSL) для этого:

val string: SpannedString = buildSpannedString {
    bold {
        append("1111")
    }
    append("neil)     
}

Больше возможностей, предоставляемых этим:

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

Наконец, вы можете просто:

textView.text = string

Ответ 11

public static Spanned getBoldString(String textNotBoldFirst, String textToBold, String textNotBoldLast) {
    String resultant = null;

    resultant = textNotBoldFirst + " " + "<b>" + textToBold + "</b>" + " " + textNotBoldLast;

    return Html.fromHtml(resultant);

}

Попробуйте это. Это может помочь определенно

Ответ 12

Сделать первый char строки spannable при поиске char в списке /recycler, например

r a vi и ajay

ранее выделение, подобное этому, но я хотел быть как ниже

ravi a nd ajay OR ravi и a jay

для этого я искал длину слова, если он равен 1, я разделил основную строку на слова и вычисленную начальную позицию слова, затем я искал слово, начинающееся с char.

 public static SpannableString colorString(int color, String text, String... wordsToColor) {
    SpannableString coloredString = new SpannableString(text);

    for (String word : wordsToColor) {

        Log.e("tokentoken", "-wrd len-" + word.length());
        if (word.length() !=1) {
            int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
            int endColorIndex = startColorIndex + word.length();
            try {
                coloredString.setSpan(new ForegroundColorSpan(color), startColorIndex, endColorIndex,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            } catch (Exception e) {
                e.getMessage();
            }
        } else {
            int start = 0;

            for (String token : text.split("[\u00A0 \n]")) {
                if (token.length() > 0) {
                    start = text.indexOf(token, start);
                   // Log.e("tokentoken", "-token-" + token + "   --start--" + start);
                    char x = token.toLowerCase().charAt(0);
                    char w = word.toLowerCase().charAt(0);
                   // Log.e("tokentoken", "-w-" + w + "   --x--" + x);

                    if (x == w) {
                        // int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
                        int endColorIndex = start + word.length();
                        try {
                            coloredString.setSpan(new ForegroundColorSpan(color), start, endColorIndex,
                                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                        } catch (Exception e) {
                            e.getMessage();
                        }
                    }
                }
            }

        }

    }

    return coloredString;
}

Ответ 13

Я пришел сюда, чтобы предложить более современное решение, потому что я не был удовлетворен существующими ответами. Мне нужно что-то, что будет работать для переведенных текстов и не имеет Html.fromHtml() производительности при использовании Html.fromHtml(). Если вы используете Kotlin, здесь есть функция расширения, которая легко выделит жирным шрифтом несколько частей вашего текста. Это работает так же, как Markdown, и может быть расширен для поддержки других тегов Markdown, если это необходимо.

val yourString = "**This** is your **string**.".makePartialTextsBold()
val anotherString = getString(R.string.something).makePartialTextsBold()

/**
 * This function requires that the parts of the string that need
 * to be bolded are wrapped in ** and ** tags
 */
fun String.makePartialTextsBold(): SpannableStringBuilder {
    var copy = this
    return SpannableStringBuilder().apply {
        var setSpan = true
        var next: String
        do {
            setSpan = !setSpan
            next = if (length == 0) copy.substringBefore("**", "") else copy.substringBefore("**")
            val start = length
            append(next)
            if (setSpan) {
                setSpan(StyleSpan(Typeface.BOLD), start, length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            copy = copy.removePrefix(next).removePrefix("**")
        } while (copy.isNotEmpty())
    }
}

Ответ 14

Ответ 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;
}

Теперь допустим, что у вас есть длинная строка, подобная этой:

String sentence = "[email protected] want to be your friend!"

И вы хотите, чтобы ваше предложение было таким, как [email protected], хотите быть вашим другом! Все, что вам нужно сделать is-, получить первое слово и получить его, чтобы сделать первое слово жирным, примерно так:

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

Теперь просто следуйте инструкциям wtsang02, например:

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

И это оно! Теперь вы должны иметь возможность выделять слово любого размера из длинного/короткого предложения. Надеюсь, это поможет кому-то, счастливое кодирование :)

Ответ 15

Вы можете добавить две строки отдельно в компоновщик, одна из которых - spannedString, а другая - обычная. Таким образом, вам не нужно рассчитывать индексы.

val instructionPress = resources?.getString(R.string.settings_press)

val okText = resources?.getString(R.string.ok)
val spannableString = SpannableString(okText)

val spannableBuilder = SpannableStringBuilder()
spannableBuilder.append(instructionPress)
spannableBuilder.append(spannableString, StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

instructionText.setText(spannableBuilder,TextView.BufferType.SPANNABLE)

Ответ 16

если положение полужирного текста является фиксированным (например, если находится в начале textView), то используйте два разных textView с одинаковым фоном. Затем вы можете сделать другой textView textStyle полужирным.

Это потребует вдвое больше памяти по сравнению с одним textView, но скорость увеличится.

Ответ 17

Я создал статический метод для установочной части текста Bold для TextView и EditText

public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(Typeface.BOLD); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text normal
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex, contentData.length()-1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
               ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
               ((EditText) mView).setText(sb);

        }
    }

Еще один индивидуальный код

  /*typeFaceStyle can be passed as 

    Typeface.NORMAL = 0;
    Typeface.BOLD = 1;
    Typeface.ITALIC = 2;
    Typeface.BOLD_ITALIC = 3;*/

    public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex,int typeFaceStyle){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(typeFaceStyle); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text italic
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex,contentData.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
                ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
                ((EditText) mView).setText(sb);
        }
    }

Ответ 18

Вы можете использовать этот код, чтобы выделить часть текста жирным шрифтом. Для всего, что находится между жирным 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;
        }

Ответ 19

Вот мое полное решение для динамических значений 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 = "Я BOLD"

CASE I, если *targetStringToFormat* = "bold" и *matchCase* = true

возвращает "Я BOLD" (так как жирный! = BOLD)

*targetStringToFormat* = "bold" II, если *targetStringToFormat* = "bold" и *matchCase* = false

возвращает "Я BOLD "

Применять:

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

Надеюсь, это поможет!

Ответ 20

Это функция расширения 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.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    )
)

,

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

Ответ 21

В случае, если кто-то использует привязку данных. Мы можем определить адаптер привязки следующим образом

@BindingAdapter("html")
fun setHtml(view: TextView, html: String) {
    view.setText(HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY))
}

Тогда мы можем использовать его в TextView

app:html="@{@string/bold_text}"

где bold_text -

<string name="bold_text"><![CDATA[Part of text is <b>bold</b>]]></string>