Как сделать часть текста жирным шрифтом в android во время выполнения?

100

ListViewВ моем приложении есть много строковых элементов , таких как name, experience, date of joiningи т.д. Я просто хотим , чтобы сделать nameсмелыми. Все строковые элементы будут в одном TextView.

мой XML:

<ImageView
    android:id="@+id/logo"
    android:layout_width="55dp"
    android:layout_height="55dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="15dp" >
</ImageView>

<TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/logo"
    android:padding="5dp"
    android:textSize="12dp" >
</TextView>

Мой код для установки TextView элемента ListView:

holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Комнатная муха
источник

Ответы:

232

Скажем, у вас есть TextViewзвонок etx. Затем вы должны использовать следующий код:

final SpannableStringBuilder sb = new SpannableStringBuilder("HELLOO");

final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); // Span to make text bold
final StyleSpan iss = new StyleSpan(android.graphics.Typeface.ITALIC); //Span to make text italic
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold 
sb.setSpan(iss, 4, 6, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make last 2 characters Italic

etx.setText(sb);

Имран Рана
источник
2
Для Xamarin используйте вот такvar bss = new StyleSpan(Android.Graphics.TypefaceStyle.Bold);
Элизабет
Для Xamarin,etx.TextFormatted = sb;
Дариус
28

Основываясь на ответе Имрана Раны, вот общий, многоразовый метод, если вам нужно применить StyleSpans к нескольким TextViews, с поддержкой нескольких языков (где индексы являются переменными):

void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style) {
    SpannableStringBuilder sb = new SpannableStringBuilder(text);
    int start = text.indexOf(spanText);
    int end = start + spanText.length();
    sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(sb);
}

Используйте его Activityтак:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    StyleSpan boldStyle = new StyleSpan(Typeface.BOLD);
    setTextWithSpan((TextView) findViewById(R.id.welcome_text),
        getString(R.string.welcome_text),
        getString(R.string.welcome_text_bold),
        boldStyle);

    // ...
}

strings.xml

<string name="welcome_text">Welcome to CompanyName</string>
<string name="welcome_text_bold">CompanyName</string>

Результат:

Добро пожаловать в CompanyName

фридерблюмль
источник
12

Приведенные здесь ответы верны, но не могут быть вызваны в цикле, потому что StyleSpanобъект представляет собой один непрерывный промежуток (не стиль, который можно применить к нескольким промежуткам). Вызов setSpanнескольких раз с одним и тем же полужирным шрифтом StyleSpanсоздаст один полужирный диапазон и просто переместит его в родительский диапазон.

В моем случае (отображение результатов поиска) мне нужно было сделать все экземпляры всех ключевых слов для поиска жирным шрифтом. Вот что я сделал:

private static SpannableStringBuilder emboldenKeywords(final String text,
                                                       final String[] searchKeywords) {
    // searching in the lower case text to make sure we catch all cases
    final String loweredMasterText = text.toLowerCase(Locale.ENGLISH);
    final SpannableStringBuilder span = new SpannableStringBuilder(text);

    // for each keyword
    for (final String keyword : searchKeywords) {
        // lower the keyword to catch both lower and upper case chars
        final String loweredKeyword = keyword.toLowerCase(Locale.ENGLISH);

        // start at the beginning of the master text
        int offset = 0;
        int start;
        final int len = keyword.length(); // let's calculate this outside the 'while'

        while ((start = loweredMasterText.indexOf(loweredKeyword, offset)) >= 0) {
            // make it bold
            span.setSpan(new StyleSpan(Typeface.BOLD), start, start+len, SPAN_INCLUSIVE_INCLUSIVE);
            // move your offset pointer 
            offset = start + len;
        }
    }

    // put it in your TextView and smoke it!
    return span;
}

Имейте в виду, что приведенный выше код недостаточно умен, чтобы пропустить двойное выделение жирным шрифтом, если одно ключевое слово является подстрокой другого. Например, если вы ищете "Fish fi" внутри «FISH in the Fisty Sea», он выделит жирным один раз слово «рыба», а затем часть «fi» . Хорошо то, что, хотя он неэффективен и немного нежелателен, он не будет иметь визуальных недостатков, поскольку отображаемый результат будет по-прежнему выглядеть как

Рыба в фи StY море

кополии
источник
Эй, чувак, можешь увидеть этот stackoverflow.com/questions/59947482/…
Пемба Таманг
8

Вы можете сделать это с помощью Kotlin и buildSpannedStringфункции расширения изcore-ktx

 holder.textView.text = buildSpannedString {
        bold { append("$name\n") }
        append("$experience $dateOfJoining")
 }
Дмитрий Леонов
источник
5

Если вы не знаете точно длину текста перед частью текста, которую хотите сделать полужирным шрифтом, или даже не знаете, что длина текста будет полужирным, вы можете легко использовать HTML-теги, например следующие:

yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));
Мухаммед Рефаат
источник
0

Расширение ответа фридерса для поддержки нечувствительности к регистру и диакритическим знакам.

public static String stripDiacritics(String s) {
        s = Normalizer.normalize(s, Normalizer.Form.NFD);
        s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
        return s;
}

public static void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style, boolean caseDiacriticsInsensitive) {
        SpannableStringBuilder sb = new SpannableStringBuilder(text);
        int start;
        if (caseDiacriticsInsensitive) {
            start = stripDiacritics(text).toLowerCase(Locale.US).indexOf(stripDiacritics(spanText).toLowerCase(Locale.US));
        } else {
            start = text.indexOf(spanText);
        }
        int end = start + spanText.length();
        if (start > -1)
            sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        textView.setText(sb);
    }
удачливый
источник
0

Если вы используете аннотацию @ srings / your_string, откройте файл strings.xml и используйте <b></b>тег в той части текста, который вам нужен.

Пример:

    <string><b>Bold Text</b><i>italic</i>Normal Text</string>
Исайяс Карвалью
источник
-1

Рекомендую использовать файл strings.xml с CDATA

<string name="mystring"><![CDATA[ <b>Hello</b> <i>World</i> ]]></string>

Затем в java файле:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
sonique
источник