Як зробити частину тексту жирним на андроїді під час виконання?


97

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

Відповіді:


230

Скажімо, у вас є телефонний 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);
Elisabeth

Для Ксамаріна,etx.TextFormatted = sb;
Дарій,

27

На основі відповіді Імрана Рани, ось загальний, багаторазовий метод, якщо вам потрібно застосувати 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/…
Пемба Таманг,

6

Ви можете зробити це за допомогою 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) ));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.