Mots en gras dans une chaîne de strings.xml sous Android

115

J'ai un long texte dans l'une des chaînes de strings.xml. Je veux mettre en gras et changer la couleur de certains mots dans ce texte.

Comment puis-je le faire?

Caroline
la source
Pouvez-vous être un peu plus précis en ce qui concerne ce que vous essayez de réaliser globalement?
Brian

Réponses:

192

Vous pouvez essentiellement utiliser des balises html dans votre ressource de chaîne comme:

<resource>
    <string name="styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

Et utilisez Html.fromHtml ou utilisez spannable, vérifiez le lien que j'ai publié.

Ancienne question similaire: est-il possible d'avoir plusieurs styles dans un TextView?

David Olsson
la source
16
De plus, selon la façon dont vous utilisez votre chaîne de ressources, vous devrez peut-être mettre les balises gras / italique dans un bloc CDATA afin qu'elles ne soient pas analysées jusqu'à ce qu'elles soient utilisées par Html.fromHtml(): ... <![CDATA[<b><i>so</i></b>]]>...
dule
133
Pour quiconque a trouvé la documentation officielle Android un peu trop vague à ce sujet: si vous utilisez des balises comme <b> dans votre ressource de chaîne, assurez-vous de la récupérer en utilisant getText(R.string.whatever)plutôt quegetString(R.string.whatever)
andygeers
1
n'est-ce pas censé être à la nameplace de id?
Hendra Anggrian
4
Donc pas besoin de Html.fromHtmlou Spannable. Utilisez simplement getText(R.string.whatever)comme @andygeers mentionné.
Alaa M.
1
@andygeers Que pouvons-nous faire pour une chaîne comme "Mon nom est <b>% s </b>" qui ne peut pas utiliser getText car elle n'accepte qu'un seul paramètre?
Taylor le
45

Utilisez la balise html dans les ressources de chaîne: -

<resources>
<string name="string_resource_name"><![CDATA[<b> Your text </b>]]> </string>
</resources>

Et obtenez du texte en gras à partir de ressources de chaîne comme: -

private Spanned getSpannedText(String text) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT);
        } else {
            return Html.fromHtml(text);
        }
    }


 String s = format(context.getResources().getString(R.string.string_resource_name));
 textView.setText(getSpannedText(s));
Sagar Chorage
la source
c'est la meilleure réponse et cela fonctionne totalement pour les personnes qui utilisent @BindingAdapter. Merci frère.
Sup.Ia
44

Comme l'a dit David Olsson, vous pouvez utiliser du HTML dans vos ressources de chaîne:

<resource>
    <string name="my_string">A string with <i>actual</i> <b>formatting</b>!</string>
</resources>

Ensuite, si vous utilisez getText(R.string.my_string)plutôt que getString(R.string.my_string)vous récupérez un CharSequenceplutôt qu'un Stringqui contient la mise en forme incorporée.

Andygeers
la source
getText renvoie CharSequence not a Spannable
Tigran Babajanyan
1
Que faire si votre chaîne est une quantité à laquelle vous devez ajouter un nombre?
Taylor le
getText ne vous permet pas d'utiliser des espaces réservés
Vincent_Paing
11

Dans kotlin, vous pouvez créer des fonctions d'extensions sur les ressources (activités | fragments | contexte) qui convertiront votre chaîne en une étendue html

par exemple

fun Resources.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Resources.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = getQuantityString(id, quantity).toHtmlSpan()

fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = getQuantityString(id, quantity, *formatArgs).toHtmlSpan()

fun String.toHtmlSpan(): Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
} else {
    Html.fromHtml(this)
}

Usage

//your strings.xml
<string name="greeting"><![CDATA[<b>Hello %s!</b><br>]]>This is newline</string>

//in your fragment or activity
resources.getHtmlSpannedString(R.string.greeting, "World")

MODIFIER encore plus d'extensions

fun Context.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Context.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()


fun Activity.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Activity.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()


fun Fragment.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Fragment.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
svkaka
la source
@Himanshu Mori un extrait de code aiderait. L'utilisez-vous en classe kotlin?
svkaka le
1
Les extensions d'activité ne sont pas nécessaires, l'activité est le contexte lui
Farshad Tahmasbi
2

Strings.xml

<string name="my_text"><Data><![CDATA[<b>Well Done !</b><br></br>All of your activities are completed.<br></br>You may now close the app.<br></br>See you again next time.]]></Data></string>

Mettre en place

textView.setText(Html.fromHtml(getString(R.string.activity_completed_text)));
kunal khedkar
la source
1

Vous pouvez le faire à partir d'une chaîne

 <resources xmlns:tools="http://schemas.android.com/tools">

 <string name="total_review"><b>Total Review: </b> </string>

 </resources>

et peut y accéder à partir du code java comme

proDuctReviewNumber.setText(getResources().getString(R.string.total_review)+productDetailsSuccess.getProductTotalReview());
Pavel
la source
1

strings.xml

<string name="sentence">This price is <b>%1$s</b> USD</string>

page.java

String successMessage = getString(R.string.message,"5.21");

Ce prix 5.21 USD

Samet ÖZTOPRAK
la source
1
Vous devez utiliser la fonctionnalité native pour passer des paramètres. Placez simplement «% 1 $ s» au lieu de «{1}» et appelez getString (R.string.message, «5.21») sans remplacer ()
Adrian Grygutis le
La documentation prend en charge cette réponse: developer.android.com/guide/topics/resources/... Bien qu'il doive être passé par un analyseur HTML
ProjectDelta