comment faire un texte spécifique sur TextView BOLD


252

Je ne sais pas comment rendre un texte spécifique sur TextView en gras.

C'est comme ça

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

Je veux que la sortie soit comme ceci:

1111 neil

idet namesont des variables dont j'ai récupéré la valeur de la base de données, et je veux mettre le iden gras, mais seulement le idafin que le namene soit pas affecté, je ne sais pas comment faire.



Réponses:


379

Construisez simplement votre chaîne en HTML et définissez-la:

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

5
Étant donné que fromHtml (sourceString) est obsolète dans l'API 24, vous devez utiliser le code suivant: Spanned durationSpanned; if (android.os.Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.N) {durationSpanned = Html.fromHtml (durationFormatted, Html.FROM_HTML_MODE_LEGACY); } else {durationSpanned = Html.fromHtml (durationFormatted); }
Mladen Rakonjac

2
C'est la seule option qui fonctionnera si vous localisez votre application.
howettl

C'est une bonne solution mais j'ai découvert que cela ne fonctionne pas pour <et> @ la solution wtsang02 est plus optimale
Omar Boshra

Cela ne fonctionne pas avec <SI vous utilisez String.format, À MOINS QUE vous n'échappiez également au crochet, comme décrit ici .
Yusuf X

5
Html.fromHtml()est désormais obsolète
Someone Somewhere

384

Bien que vous puissiez utiliser Html.fromHtml (), vous pouvez utiliser une approche plus native qui est SpannableStringBuilder , ce message peut être utile.

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

Si cette réponse ne fonctionne pas, essayez d'ajouter votre texte avec une chaîne pouvant être étendue, quelque chose comme: mSpannable.append (yourremainingtext);
Gowtham Kumar

11
Pour les personnes venant de Google sans connaissance préalable: INT_START / INT_END sont l'endroit où le gras doit commencer et se terminer.
Spotlight

2
si vous avez seulement besoin d'appliquer du balisage à la chaîne source sans le changer, alors vous feriez mieux d'utiliser la classe
SpannableString

26
Cela se cassera complètement si vous devez localiser votre copie. INT_START et INT_END seront des positions différentes dans différentes localisations.
howettl

5
Essayez de comprendre ce que fait le code en cas de doute. Le début int est un nombre que vous définissez, qui est l'indice de début de la plage. Essayez 0 pour démarrer, string. (). Size () pour end.
wtsang02

85

Premièrement: vous n'avez pas à vous soucier de l'utilisation du code de performances lentes de la réponse de Raghav Sood .

Deuxièmement: vous n'avez pas besoin d'écrire une fonction d'extension fournie par la réponse de w3bshark lorsque vous utilisez Kotlin.

Finnaly: Tout ce que vous devez faire est d'utiliser la bibliothèque Kotlin android-ktx de Google (référez-vous ici pour trouver plus d'informations et comment l'inclure dans votre projet):

// Suppose id = 1111 and name = neil (just what you want). 
val s = SpannableStringBuilder()
          .bold { append(id) } 
          .append(name)
txtResult.setText(s) 

Produit: 1111 neil


METTRE À JOUR:

Parce que je pense que cela peut aider quelqu'un d'autre et montrer jusqu'où vous pouvez aller ici sont plus de cas d'utilisation.

  • Lorsque vous devez afficher un texte avec certaines parties en bleu et en italique:

    val myCustomizedString = SpannableStringBuilder()
        .color(blueColor, { append("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
  • Lorsque vous devez afficher un texte en gras et en italique:

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

Bref, bold, append, coloret italicsont des fonctions d'extension à SpannableStringBuilder. Vous pouvez voir une autre fonction d'extension dans la documentation officielle , d'où vous pouvez penser à d'autres possibilités.


C'est génial et tout, mais je pense que chaque réponse liée aux chaînes devrait envisager des traductions. Les mots dans les phrases peuvent être ordonnés et structurés complètement différemment dans certaines langues, donc l'ajout de ce type n'est pas toujours applicable dans certaines situations. Aussi pas idéal pour des trucs comme des chaînes de quantité en XML.
Edward van Raak

1
@CoolMind Cela ne vous empêche pas d'utiliser Android KTX. Vous pouvez trouver des informations sur github.com/android/android-ktx sur la façon de signaler un bogue, de faire une suggestion de fonctionnalité ou de contribuer à cette bibliothèque. C'est donc toujours une référence valable. J'ai mis à jour ma réponse pour inclure plus d'informations sur la bibliothèque et comment l'utiliser dans votre projet.
Filipe Brito

1
donnez à ce gars une médaille pour cette solution et ressource moderne !! Merci!!!
SJD

37

J'ai pensé que la réponse choisie n'avait pas donné de résultat satisfaisant. J'ai écrit ma propre fonction qui prend 2 chaînes; Le texte intégral et la partie du texte que vous souhaitez mettre en gras.

Il renvoie un SpannableStringBuilder avec le 'textToBold' de 'text' en gras.

Je trouve la possibilité de rendre une sous-chaîne en gras sans l'envelopper dans des balises utiles.

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

Pouvez-vous fournir un exemple d'utilisation de ce code dans le code?
Micro

2
@MicroR Vous devez passer deux chaînes, la deuxième chaîne doit être une section de texte contenue dans la première. par exemple makeSectionOfTextBold ("Ceci est un excellent texte.", "génial").
Leon

1
vous devez changer votre instruction if avec if (textToBold! = null &&! textToBold.isEmpty ())
Arda Kara

2
Cette fonction ne s'attend pas à ce que la sous-chaîne puisse apparaître plusieurs fois en texte intégral. Par exemple, dans "Mon nom d'utilisateur est nom", il ne peut pas mettre le 2ème "nom" en gras.
Jadamec

1
Ensuite, cette méthode devrait en fait être nommée makeAllBold (text, textToBold).
wtsang02

30

Comme l'a dit wtsang02, l'utilisation de HTML est une surcharge coûteuse. Utilisez simplement la solution native. Si vous n'avez pas à modifier la chaîne, utilisez simplement SpannableString, pas 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);

23

Si vous souhaitez utiliser la chaîne de XML, vous pouvez faire quelque chose comme ceci:

strings.xml (la partie "CDATA" est importante, sinon cela ne fonctionnera pas)

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

fichier de mise en page

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

code

textView.text = HtmlCompat.fromHtml(getString(R.string.test), HtmlCompat.FROM_HTML_MODE_LEGACY)

Cela fonctionne pour moi <string name="test"><b>text bold</b> other text</string>. Ne fonctionne pas si j'écris<![CDATA[
Sara

@sara Testé à nouveau maintenant, sur Pixel 2 avec Q. Fonctionne très bien. Ici, j'ai mis à jour comment cela fonctionne avec Kotlin. Veuillez réessayer.
développeur Android

C'est la réponse acceptable si vous utilisez des polices personnalisées. Kudus au creater.
Raghul Sugathan

13

Il suffit de fermer le texte spécifié comme celui-ci par exemple <b>"your text here:"</b>

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

résultat: Siège: Mooresville, Caroline du Nord, États-Unis


Cela ne fonctionne que si la chaîne est utilisée à partir de xml. Si cette chaîne est appelée par programme, l'encodage html est supprimé.
Starwave

11

Si vous utilisez Kotlin, cela devient encore plus facile à faire en utilisant core-ktx, car il fournit un langage spécifique au domaine (DSL) pour ce faire:

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

Plus d'options fournies par lui sont:

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

Enfin, vous pouvez simplement:

textView.text = string

10

Voici une meilleure solution si vous souhaitez mettre plusieurs textes en gras. J'ai amélioré le code d'Eitan. merci 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

Sur la base de la réponse de @ mladj0ni, j'ai obtenu le code ci-dessous pour fonctionner. Le problème était que si vous utilisez String.format , il supprime le balisage html, vous devez donc échapper les symboles de crochet dans 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);

C'est plus simple que SpannableStringBuilder. En ce qui concerne les performances, si vous affichez une seule chaîne, l'utilisateur ne remarquera pas la milliseconde supplémentaire pour l'analyser.

Voir la documentation ici .


Merci pour & lt; b> ... & lt; / b>
oxied

4

Vous pouvez utiliser ce code pour mettre une partie de votre texte en gras. Pour tout ce qui se trouve entre les balises html en gras, cela le rendra en gras.

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

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

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

    return Html.fromHtml(resultant);

}

Essaye ça. Cela peut certainement aider


3

Rendre le premier caractère de la chaîne extensible lors de la recherche du caractère dans la liste / recycleur comme

r a vi et ajay

mettant en évidence précédemment comme ça, mais je voulais être comme ci-dessous

ravi a nd ajay OU ravi et un geai

pour cela j'ai cherché la longueur du mot si elle est égale à 1, j'ai séparé la chaîne principale en mots et calculé la position de départ du mot puis j'ai cherché le mot commençant par 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;
}

3

Je suis venu ici pour fournir une solution plus à jour, car je n'étais pas satisfait des réponses existantes. J'avais besoin de quelque chose qui fonctionnerait pour les textes traduits et qui n'aurait pas la performance de l'utilisation Html.fromHtml(). Si vous utilisez Kotlin, voici une fonction d'extension qui mettra facilement plusieurs parties de votre texte en gras . Cela fonctionne exactement comme Markdown et pourrait être étendu pour prendre en charge d'autres balises Markdown, si besoin est.

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

3

wtsang02 réponse est la meilleure façon de procéder, car Html.fromHtml ("") est désormais obsolète. Ici, je vais juste l'améliorer un peu pour quiconque a du mal à rendre dynamiquement le premier mot en gras, quelle que soit la taille de la phrase.

Commençons par créer une méthode pour obtenir le premier mot:

 private String getFirstWord(String input){

    for(int i = 0; i < input.length(); i++){

        if(input.charAt(i) == ' '){

            return input.substring(0, i);
        }
    }

    return input;
}

Supposons maintenant que vous ayez une longue chaîne comme celle-ci:

String sentence = "friendsAwesomeName@gmail.com want's to be your friend!"

Et vous voulez que votre phrase soit comme yourAwesomeName@gmail.com veut être votre ami! Tout ce que vous avez à faire est d'obtenir le premier mot et d'obtenir sa longueur pour rendre le premier mot en gras, quelque chose comme ceci:

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

Maintenant, suivez simplement les étapes de wtsang02 , comme ceci:

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

Et c'est tout! Vous devriez maintenant être en mesure de mettre en gras un mot de n'importe quelle taille dans une phrase longue / courte. J'espère que cela aidera quelqu'un, codage heureux :)


3

Ceci est la fonction d'extension Kotlin que j'utilise pour cela

/**
 * 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)
}

Usage:

text_view.text="something bold"
text_view.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    )
)

.

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

2

Vous pouvez ajouter les deux chaînes séparément dans le générateur, l'une d'entre elles est spannedString, l'autre est une chaîne régulière. De cette façon, vous n'avez pas à calculer les index.

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)

2

si la position du texte en gras est fixe (ex: si se trouve au début de textView), alors utilisez deux textView différents avec le même arrière-plan. Ensuite, vous pouvez mettre en gras le textStyle de l'autre textView.

Cela nécessitera deux fois la mémoire par rapport à une seule TextView mais la vitesse augmentera.


1

J'ai créé une méthode statique pour définir une partie du texte en gras pour TextView et 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);

        }
    }

Un autre code plus personnalisé

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

1

Dans le cas où quelqu'un utilise la liaison de données. Nous pouvons définir un adaptateur de liaison comme celui-ci

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

Ensuite, nous pouvons l'utiliser sur un TextView

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

où bold_text est

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

Où écrivez-vous la fonction "setHtml"?
développeur Android

developer.android.com/topic/libraries/data-binding/… C'est essentiellement n'importe quelle classe, tant que vous avez une annotation
logcat

Oh, c'est tellement bizarre pour moi. Je vous remercie. Connaissez-vous peut-être un joli tutoriel / échantillon pour les nouveaux arrivants de ce sujet?
développeur Android

Je ne connais pas de tutoriels. Juste google "android BindingAdapter"
logcat

1

Trouvé un moyen au cas où vous voudriez gérer la localisation dans plusieurs langues, c'est ennuyeux à faire mais ça marche, supposons que nous voulons ceci:

En anglais:

Aucun paiement enregistré

En espagnol:

Pas de foin pagos registrados

Vous devez créer 3 chaînes

Anglais:

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

Espagnol:

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

Vous pouvez maintenant le faire:

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)

1

Votre ressource String

<resources>
   <string name="your_string_resource_name">This is normal text<![CDATA[<b> but this is bold </b>]]> and <![CDATA[<u> but this is underline text</u>]]></string>
</resources> 

votre classe java

yourtextView.setText(getString(R.string.your_string_resource_name));

0

Voici ma solution complète pour les valeurs de chaîne dynamiques avec vérification de la casse.

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

Par exemple. completeString = "Je suis BOLD"

CAS I si *targetStringToFormat* = "bold"et*matchCase* = true

renvoie "Je suis BOLD" (car gras! = BOLD)

CAS II si *targetStringToFormat* = "bold"et*matchCase* = false

renvoie "je suis BOLD "

Postuler:

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

J'espère que cela pourra aider!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.