Comment rendre une partie du texte en gras dans Android au moment de l'exécution?

97

A ListViewdans mon application comporte de nombreux éléments de chaîne comme name, experience, date of joining, etc. Je veux juste faire namegras. Tous les éléments de chaîne seront dans un seul TextView.

mon 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>

Mon code pour définir le TextView de l'élément ListView:

holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Mouche domestique
la source

Réponses:

230

Dites que vous avez un TextViewappelé etx. Vous utiliseriez alors le code suivant:

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

Imran Rana
la source
2
Pour Xamarin, utilisez comme cecivar bss = new StyleSpan(Android.Graphics.TypefaceStyle.Bold);
Elisabeth
Pour Xamarin,etx.TextFormatted = sb;
Darius
27

Sur la base de la réponse d'Imran Rana, voici une méthode générique et réutilisable si vous devez appliquer StyleSpans à plusieurs TextViews, avec prise en charge de plusieurs langues (où les indices sont variables):

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

Utilisez-le de Activitymanière similaire:

@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>

Résultat:

Bienvenue sur CompanyName

friederbluemle
la source
12

Les réponses fournies ici sont correctes, mais ne peuvent pas être appelées dans une boucle car l' StyleSpanobjet est une seule étendue contiguë (pas un style qui peut être appliqué à plusieurs travées). Appeler setSpanplusieurs fois avec le même gras StyleSpancréerait une plage en gras et la déplacerait simplement dans la plage parent.

Dans mon cas (affichage des résultats de recherche), je devais mettre en gras toutes les instances de tous les mots-clés de recherche. C'est ce que j'ai fait:

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

Gardez à l'esprit que le code ci-dessus n'est pas assez intelligent pour ignorer les doubles caractères gras si un mot clé est une sous-chaîne de l'autre. Par exemple, si vous recherchez "Fish fi" dans "Fishes in the fisty Sea", cela rendra le "poisson" en gras une fois, puis la partie "fi" . La bonne chose est que bien qu'il soit inefficace et un peu indésirable, il n'aura pas d'inconvénient visuel car votre résultat affiché ressemblera toujours à

Poisson es dans la fi mer sty

copolii
la source
hey man pouvez-vous s'il vous plaît voir ce stackoverflow.com/questions/59947482/…
Pemba Tamang le
6

Vous pouvez le faire en utilisant Kotlin et la buildSpannedStringfonction d'extension decore-ktx

 holder.textView.text = buildSpannedString {
        bold { append("$name\n") }
        append("$experience $dateOfJoining")
 }
Dmitrii Leonov
la source
5

si vous ne connaissez pas exactement la longueur du texte avant la partie de texte que vous souhaitez mettre en gras, ou même si vous ne connaissez pas la longueur du texte à mettre en gras, vous pouvez facilement utiliser des balises HTML comme les suivantes:

yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));
Muhammed Refaat
la source
0

Extension de la réponse de frieder pour soutenir l'insensibilité des cas et des signes diacritiques.

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);
    }
luky
la source
0

Si vous utilisez l'annotation @ srings / your_string, accédez au fichier strings.xml et utilisez la <b></b>balise dans la partie du texte souhaitée.

Exemple:

    <string><b>Bold Text</b><i>italic</i>Normal Text</string>
Isaias Carvalho
la source
-1

Je recommande d'utiliser le fichier strings.xml avec CDATA

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

Puis dans le fichier java:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
sonique
la source