Ressources de chaîne

Une ressource de chaîne fournit des chaînes de texte à votre application avec un style et une mise en forme facultatifs. Trois types de ressources peuvent fournir à votre application des chaînes :

Chaîne
Ressource XML qui fournit une seule chaîne.
Tableau de chaînes
Ressource XML qui fournit un tableau composé de plusieurs chaînes.
Chaînes de quantité (pluriels)
Ressource XML comportant différentes chaînes pour la pluralisation.

Toutes les chaînes peuvent appliquer des balises de style et des arguments de mise en forme. Pour en savoir plus sur le style et la mise en forme des chaînes, consultez la section Mise en forme et style.

Chaîne

Chaîne unique qui peut être référencée à partir de l'application ou d'autres fichiers de ressources (tels qu'une mise en page XML).

Remarque : Une chaîne est une ressource simple référencée à l'aide de la valeur fournie dans l'attribut name (et non à l'aide du nom du fichier XML). Vous pouvez ainsi combiner des ressources de chaîne et d'autres ressources simples dans le même fichier XML, dans un seul élément <resources>.

Emplacement du fichier :
res/values/filename.xml
Le nom de fichier est arbitraire. Le nom (name) de l'élément <string> est utilisé comme ID de ressource.
Type de données de la ressource compilée :
Pointeur de ressource vers un élément String.
Référence de la ressource :
En Java : R.string.string_name
En XML :@string/string_name
Syntaxe :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string
        name="string_name"
        >text_string</string>
</resources>
Éléments :
<resources>
Obligatoire. Il doit s'agir du nœud racine.

Aucun attribut.

<string>
Chaîne pouvant inclure des balises de style. Pensez à ajouter un caractère d'échappement aux apostrophes et aux guillemets. Pour savoir comment styliser et mettre en forme correctement les chaînes, consultez Mise en forme et style ci-dessous.

Attributs :

name
Chaîne. Nom de la chaîne. Ce nom est utilisé comme ID de ressource.
Exemple :
Fichier XML enregistré sous res/values/strings.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>

Ce fichier XML de mise en page applique une chaîne à une vue :

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello" />

Ce code d'application récupère une chaîne :

Kotlin

val string: String = getString(R.string.hello)

Java

String string = getString(R.string.hello);

Vous pouvez utiliser getString(int) ou getText(int) pour récupérer une chaîne. getText(int) conserve tout style de texte enrichi appliqué à la chaîne.

Tableau de chaînes

Tableau de chaînes qui peuvent être référencées à partir de l'application.

Remarque : Un tableau de chaînes est une ressource simple référencée à l'aide de la valeur fournie dans l'attribut name (et non à l'aide du nom du fichier XML). Vous pouvez ainsi combiner les ressources d'un tableau de chaînes avec d'autres ressources simples dans le même fichier XML, sous un seul élément <resources>.

Emplacement du fichier :
res/values/filename.xml
Le nom de fichier est arbitraire. Le nom (name) de l'élément <string-array> est utilisé comme ID de ressource.
Type de données de la ressource compilée :
Pointeur de ressource vers un tableau d'éléments String.
Référence de la ressource :
En Java : R.array.string_array_name
En XML : @[package:]array/string_array_name
Syntaxe :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
        name="string_array_name">
        <item
            >text_string</item>
    </string-array>
</resources>
Éléments :
<resources>
Obligatoire. Il doit s'agir du nœud racine.

Aucun attribut.

<string-array>
Définit un tableau de chaînes. Contient un ou plusieurs éléments <item>.

Attributs :

name
Chaîne. Nom du tableau. Ce nom est utilisé comme ID de ressource pour référencer le tableau.
<item>
Chaîne pouvant inclure des balises de style. La valeur peut être une référence à une autre ressource de chaîne. Doit être un enfant d'un élément <string-array>. Pensez à ajouter un caractère d'échappement aux apostrophes et aux guillemets. Pour en savoir plus sur le style et la mise en forme corrects des chaînes, consultez la section Mise en forme et style ci-dessous.

Aucun attribut.

Exemple :
Fichier XML enregistré sous res/values/strings.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="planets_array">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
    </string-array>
</resources>

Ce code d'application récupère un tableau de chaînes :

Kotlin

val array: Array<String> = resources.getStringArray(R.array.planets_array)

Java

Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);

Chaînes de quantité (pluriels)

L'accord grammatical avec la quantité varie selon les langues. En français, par exemple, la quantité 1 est un cas particulier. Nous écrivons "1 livre", mais pour toute autre quantité, nous écrivons "n livres". Cette distinction entre singulier et pluriel est très courante, mais d'autres langages font des distinctions plus précises. L'ensemble complet compatible avec Android est zero, one, two, few, many et other.

Les règles qui permettent de choisir le cas d'utilisation pour une langue et une quantité spécifiques peuvent être très complexes. C'est pourquoi Android fournit des méthodes telles que getQuantityString() pour sélectionner la ressource qui vous convient.

Bien qu'auparavant appelées "chaînes de quantité" (et toujours appelées ainsi dans l'API), les chaînes de quantité doivent seulement être utilisées pour les pluriels. L'utilisation de chaînes de quantité pour implémenter un élément comme "Boîte de réception" par rapport à "Boîte de réception (12)" dans Gmail en cas de messages non lus, par exemple, serait une erreur. Bien qu'il puisse sembler pratique d'utiliser des chaînes de quantité au lieu d'une instruction if, il est important de noter que certaines langues (comme le chinois) ne font pas du tout ce type de différences grammaticales. Vous aurez donc toujours la chaîne other.

La sélection de la chaîne à utiliser dépend uniquement de la nécessité grammaticale. En anglais, la chaîne zero est ignorée même si la quantité est nulle, car 0 n'est pas grammaticalement différent de 2 ni de n'importe quel autre nombre, à part 1 qui n'utilise pas le pluriel. En effet, en anglais, 0 implique toujours l'utilisation d'un pluriel comme pour la plupart des autres nombres ("0 books", "1 book", "2 books", etc.). À l'inverse, en coréen, seule la chaîne other est utilisée.

Ne vous laissez pas non plus duper par le fait que, par exemple, two semble s'appliquer uniquement à la quantité 2 : une langue peut exiger que 2, 12, 102 (et ainsi de suite) soient tous traités les uns comme les autres, mais différemment des autres quantités. Demandez à un traducteur de confiance quelles distinctions doivent être prises en compte.

Si votre message ne contient pas le nombre réel d'unités, il n'est probablement pas adapté au pluriel. Par exemple, en lituanien, le singulier est utilisé pour 1 et 101. Ainsi, "1 livre" est traduit par "1 knyga", et "101 livres" par "101 knyga". Par ailleurs, "un livre" correspond à "knyga", et "beaucoup de livres" à "daug knygų". Si un message au pluriel en français contient "un livre" (singulier) et "beaucoup de livres" (pluriel) sans le nombre réel, il peut être traduit par "knyga" (un livre)/"daug knygų" (beaucoup de livres). Toutefois, avec les règles lituaniennes, il affichera "knyga" (un seul livre) lorsque le nombre correspond à 101.

Il est souvent possible d'éviter les chaînes de quantité avec des formulations neutres telles que "Nombre de livres : 1". Cette approche vous facilite la vie et celle de vos traducteurs, s'il s'agit d'un style acceptable pour votre application.

À partir de l'API 24, vous pouvez utiliser la classe ICU MessageFormat qui offre beaucoup plus de possibilités.

Remarque : Une collection de pluriels est une ressource simple référencée à l'aide de la valeur fournie dans l'attribut name (et non à l'aide du nom du fichier XML). Vous pouvez ainsi combiner des ressources de pluriels avec d'autres ressources simples dans le même fichier XML, dans un seul élément <resources>.

Emplacement du fichier :
res/values/filename.xml
Le nom de fichier est arbitraire. Le nom (name) de l'élément <plurals> est utilisé comme ID de ressource.
Référence de la ressource :
En Java : R.plurals.plural_name
Syntaxe :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals
        name="plural_name">
        <item
            quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
            >text_string</item>
    </plurals>
</resources>
Éléments :
<resources>
Obligatoire. Il doit s'agir du nœud racine.

Aucun attribut.

<plurals>
Collection de chaînes, parmi lesquelles une chaîne est fournie en fonction d'une quantité. Contient un ou plusieurs éléments <item>.

Attributs :

name
Chaîne. Nom de la paire de chaînes. Ce nom est utilisé comme ID de ressource.
<item>
Chaîne au pluriel ou au singulier. La valeur peut être une référence à une autre ressource de chaîne. Doit être un enfant d'un élément <plurals>. Pensez à ajouter un caractère d'échappement aux apostrophes et aux guillemets. Pour en savoir plus sur le style et la mise en forme corrects des chaînes, consultez la section Mise en forme et style ci-dessous.

Attributs :

quantity
Mot clé. Valeur indiquant quand cette chaîne doit être utilisée. Voici les valeurs valides, avec des exemples non exhaustifs entre parenthèses :
ValeurDescription
zeroLorsque la langue nécessite un traitement spécial du chiffre 0 (comme en arabe).
oneLorsque la langue nécessite le traitement spécial de chiffres comme un (comme c'est le cas du chiffre 1 en français et dans la plupart des autres langues ; en russe, tout chiffre se terminant par 1, mais pas par 11 est compris dans cette classe).
twoLorsque la langue nécessite un traitement spécial des chiffres comme deux (comme pour 2 en gallois ou 102 en slovène).
fewLorsque la langue nécessite un traitement spécial des "petits" chiffres (comme 2, 3 et 4 en tchèque, ou les nombres se terminant par 2, 3 ou 4, mais pas 12, 13 ou 14 en polonais).
manyLorsque la langue nécessite un traitement spécial des "grands" chiffres (comme ceux se terminant par 11-99 en maltais).
otherLorsque la langue ne nécessite pas de traitement particulier de la quantité donnée (comme pour tous les chiffres en chinois ou 42 en français).
Exemple :
Fichier XML enregistré sous res/values/strings.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals name="numberOfSongsAvailable">
        <!--
             As a developer, you should always supply "one" and "other"
             strings. Your translators will know which strings are actually
             needed for their language. Always include %d in "one" because
             translators will need to use %d for languages where "one"
             doesn't mean 1 (as explained above).
          -->
        <item quantity="one">%d song found.</item>
        <item quantity="other">%d songs found.</item>
    </plurals>
</resources>

Fichier XML enregistré sous res/values-pl/strings.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals name="numberOfSongsAvailable">
        <item quantity="one">Znaleziono %d piosenkę.</item>
        <item quantity="few">Znaleziono %d piosenki.</item>
        <item quantity="other">Znaleziono %d piosenek.</item>
    </plurals>
</resources>

Utilisation :

Kotlin

val count = getNumberOfSongsAvailable()
val songsFound = resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count)

Java

int count = getNumberOfSongsAvailable();
Resources res = getResources();
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);

Lorsque vous utilisez la méthode getQuantityString(), vous devez transmettre count deux fois si votre chaîne inclut une mise en forme avec un nombre. Par exemple, pour la chaîne %d songs found, le premier paramètre count sélectionne la chaîne appropriée au pluriel, et le second paramètre count est inséré dans l'espace réservé %d. Si vos chaînes au pluriel n'incluent pas de mise en forme de chaîne, vous n'avez pas besoin de transmettre le troisième paramètre à getQuantityString.

Mise en forme et style

Voici quelques points importants à connaître sur la mise en forme et le style des ressources de chaîne.

Gérer les caractères spéciaux

Lorsqu'une chaîne contient des caractères ayant un usage particulier en XML, vous devez les échapper conformément aux règles d'échappement XML/HTML standards. Si vous devez échapper un caractère ayant une signification particulière dans Android, vous devez utiliser une barre oblique inverse avant le caractère concerné.

Par défaut, Android réduit les séquences d'espaces blancs en un seul espace. Pour éviter cela, placez la partie pertinente de la chaîne entre des guillemets doubles. Dans ce cas, tous les espaces blancs (y compris les nouvelles lignes) seront conservés dans la zone entourée par les guillemets. Les guillemets doubles vous permettent également d'utiliser des guillemets simples, sans échappement.

Caractère Forme(s) avec échappement
@ \@
? \?
Nouvelle ligne \n
Tabulation \t
Caractère Unicode U+XXXX \uXXXX
Guillemet simple (')

Au choix :

  • \'
  • Placez la chaîne entière entre guillemets doubles ("This'll work", par exemple).
Guillemet double (") \"

Notez que le fait de délimiter la chaîne avec des guillemets simples ne fonctionne pas.

Les espaces blancs sont réduits, et l'échappement Android se produit une fois que le fichier de ressources est analysé au format XML. En d'autres termes, <string> &#32; &#8200; &#8195;</string> (espace, espace de ponctuation, espace cadratin Unicode) est converti en un seul espace (" "), car ce sont tous des espaces Unicode après l'analyse du fichier au format XML. Pour conserver ces espaces tels quels, vous pouvez les mettre entre guillemets (<string>" &#32; &#8200; &#8195;"</string>) ou utiliser l'échappement Android (<string> \u0032 \u8200 \u8195</string>).

Remarque : Du point de vue de l'analyseur XML, il n'existe aucune différence entre <string>"Test this"</string> et <string>&quot;Test this&quot;</string>. Ces deux formes n'affichent pas de guillemets, mais déclenchent des guillemets Android préservant les espaces blancs (ce qui n'aura aucun effet pratique dans ce cas).

Mettre en forme des chaînes

Si vous devez mettre en forme des chaînes, placez les arguments de mise en forme dans la ressource de chaîne, comme illustré dans l'exemple de ressource suivant.

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

Dans cet exemple, la chaîne de mise en forme comprend deux arguments : %1$s est une chaîne, et %2$d est un nombre décimal. Appelez ensuite getString(int, Object...) pour mettre en forme la chaîne. Par exemple :

Kotlin

var text = getString(R.string.welcome_messages, username, mailCount)

Java

String text = getString(R.string.welcome_messages, username, mailCount);

Ajouter des styles avec le balisage HTML

Vous pouvez ajouter des styles à vos chaînes à l'aide du balisage HTML. Par exemple :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome">Welcome to <b>Android</b>!</string>
</resources>

Voici les éléments HTML acceptés :

  • Gras : <b>
  • Italique : <i>, <cite>, <dfn>, <em>
  • Texte 25 % plus grand : <big>
  • Texte 20 % plus petit : <small>
  • Définir les propriétés de la police : <font face="font_family" color="hex_color">. monospace, serif et sans_serif sont des exemples de familles de polices possibles.
  • Définir une famille de polices à chasse fixe : <tt>
  • Barré : <s>, <strike>, <del>
  • Souligné : <u>
  • Exposant : <sup>
  • Indice : <sub>
  • Puces : <ul>, <li>
  • Sauts de ligne : <br>
  • Division : <div>
  • Style CSS : <span style="color|background_color|text-decoration">
  • Paragraphes : <p dir="rtl | ltr" style="…">

Si vous n'appliquez pas de mise en forme, vous pouvez définir du texte TextView directement en appelant setText(java.lang.CharSequence). Toutefois, dans certains cas, vous pouvez créer une ressource de texte stylisée qui servira également de chaîne de mise en forme. Normalement, cette approche ne fonctionne pas, car les méthodes format(String, Object...) et getString(int, Object...) suppriment toutes les informations de style de la chaîne. La solution consiste à écrire les balises HTML avec des entités avec échappement, qui sont ensuite récupérées avec fromHtml(String), après la mise en forme. Par exemple :

  1. Stockez votre ressource de texte stylisé sous la forme d'une chaîne avec échappement HTML :
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>
    

    Dans cette chaîne mise en forme, un élément <b> est ajouté. Notez que le crochet d'ouverture comporte un échappement HTML et utilise la notation &lt;.

  2. Ensuite, mettez en forme la chaîne comme d'habitude, mais appelez fromHtml(String) pour convertir le texte HTML en texte stylisé :

    Kotlin

    val text: String = getString(R.string.welcome_messages, username, mailCount)
    val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
    

    Java

    String text = getString(R.string.welcome_messages, username, mailCount);
    Spanned styledText = Html.fromHtml(text, FROM_HTML_MODE_LEGACY);
    

Étant donné que la méthode fromHtml(String) met en forme toutes les entités HTML, veillez à échapper tous les caractères HTML possibles dans les chaînes que vous utilisez avec le texte mis en forme, à l'aide de htmlEncode(String). Par exemple, si vous mettez en forme une chaîne contenant des caractères tels que "<" ou "&", ils doivent être échappés avant la mise en forme. De cette manière, lorsque la chaîne mise en forme sera transmise via fromHtml(String), les caractères apparaîtront comme ils ont été écrits initialement. Par exemple :

Kotlin

val escapedUsername: String = TextUtils.htmlEncode(username)

val text: String = getString(R.string.welcome_messages, escapedUsername, mailCount)
val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)

Java

String escapedUsername = TextUtils.htmlEncode(username);

String text = getString(R.string.welcome_messages, escapedUsername, mailCount);
Spanned styledText = Html.fromHtml(text);

Ajouter des styles avec des spannables

Un Spannable est un objet texte que vous pouvez styliser avec des propriétés de police telles que la couleur et l'épaisseur de la police. Utilisez SpannableStringBuilder pour créer le texte, puis appliquez-lui des styles définis dans le package android.text.style.

Vous pouvez utiliser les méthodes d'assistance suivantes pour configurer une grande partie du travail de création de texte spannable :

Kotlin

/**
 * Returns a CharSequence that concatenates the specified array of CharSequence
 * objects and then applies a list of zero or more tags to the entire range.
 *
 * @param content an array of character sequences to apply a style to
 * @param tags the styled span objects to apply to the content
 *        such as android.text.style.StyleSpan
 */
private fun apply(content: Array<out CharSequence>, vararg tags: Any): CharSequence {
    return SpannableStringBuilder().apply {
        openTags(tags)
        content.forEach { charSequence ->
            append(charSequence)
        }
        closeTags(tags)
    }
}

/**
 * Iterates over an array of tags and applies them to the beginning of the specified
 * Spannable object so that future text appended to the text will have the styling
 * applied to it. Do not call this method directly.
 */
private fun Spannable.openTags(tags: Array<out Any>) {
    tags.forEach { tag ->
        setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK)
    }
}

/**
 * "Closes" the specified tags on a Spannable by updating the spans to be
 * endpoint-exclusive so that future text appended to the end will not take
 * on the same styling. Do not call this method directly.
 */
private fun Spannable.closeTags(tags: Array<out Any>) {
    tags.forEach { tag ->
    if (length > 0) {
            setSpan(tag, 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        } else {
            removeSpan(tag)
        }
    }
}

Java

/**
 * Returns a CharSequence that concatenates the specified array of CharSequence
 * objects and then applies a list of zero or more tags to the entire range.
 *
 * @param content an array of character sequences to apply a style to
 * @param tags the styled span objects to apply to the content
 *        such as android.text.style.StyleSpan
 *
 */
private static CharSequence applyStyles(CharSequence[] content, Object[] tags) {
    SpannableStringBuilder text = new SpannableStringBuilder();
    openTags(text, tags);
    for (CharSequence item : content) {
        text.append(item);
    }
    closeTags(text, tags);
    return text;
}

/**
 * Iterates over an array of tags and applies them to the beginning of the specified
 * Spannable object so that future text appended to the text will have the styling
 * applied to it. Do not call this method directly.
 */
private static void openTags(Spannable text, Object[] tags) {
    for (Object tag : tags) {
        text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK);
    }
}

/**
 * "Closes" the specified tags on a Spannable by updating the spans to be
 * endpoint-exclusive so that future text appended to the end will not take
 * on the same styling. Do not call this method directly.
 */
private static void closeTags(Spannable text, Object[] tags) {
    int len = text.length();
    for (Object tag : tags) {
        if (len > 0) {
            text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            text.removeSpan(tag);
        }
    }
}

Les méthodes bold, italic et color suivantes encapsulent les méthodes d'assistance ci-dessus et illustrent des exemples spécifiques d'application de styles définis dans le package android.text.style. Vous pouvez créer des méthodes similaires pour appliquer d'autres types de styles de texte.

Kotlin

/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
fun bold(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.BOLD))

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
fun italic(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.ITALIC))

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
fun color(color: Int, vararg content: CharSequence): CharSequence =
        apply(content, ForegroundColorSpan(color))

Java

/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence bold(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.BOLD));
}

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence italic(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.ITALIC));
}

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
public static CharSequence color(int color, CharSequence... content) {
    return apply(content, new ForegroundColorSpan(color));
}

Voici un exemple d'association de ces méthodes pour appliquer différents styles à des mots individuels au sein d'une expression :

Kotlin

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
val text: CharSequence = bold(italic(getString(R.string.hello)),
        color(Color.RED, getString(R.string.world)))

Java

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
CharSequence text = bold(italic(getString(R.string.hello)),
    color(Color.RED, getString(R.string.world)));

Le module Kotlin core-ktx contient également des fonctions d'extension qui facilitent l'utilisation des objets Span. Pour en savoir plus, consultez la documentation du package android.text sur GitHub.

Pour en savoir plus sur l'utilisation des objets Span, consultez les liens suivants :

Ajouter des styles avec des annotations

Vous pouvez appliquer des styles complexes ou personnalisés en utilisant la classe Annotation avec la balise <annotation> dans vos fichiers de ressources string.xml. La balise d'annotation vous permet de marquer des parties de la chaîne pour qu'un style personnalisé lui soit appliqué. Pour ce faire, vous devez définir des paires clé/valeur personnalisées dans le code XML que le framework convertira ensuite en objets Span Annotation. Vous pourrez ensuite récupérer ces annotations, et utiliser la clé et la valeur pour appliquer le style.

Lorsque vous créez des annotations, veillez à ajouter la balise <annotation> à toutes les traductions de la chaîne dans chaque fichier string.xml.


Appliquer une police de caractères personnalisée au mot "texte" dans toutes les langues

Exemple : Ajouter une police de caractères personnalisée

  1. Ajoutez la balise <annotation> et définissez la paire clé-valeur. Dans le cas présent, la clé est font, et la valeur correspond au type de police que nous souhaitons utiliser : title_emphasis.

    // values/strings.xml
    <string name="title">Best practices for <annotation font="title_emphasis">text</annotation> on Android</string>
    
    // values-es/strings.xml
    <string name="title"><annotation font="title_emphasis">Texto</annotation> en Android: mejores prácticas</string>
    
  2. Chargez la ressource de chaîne et recherchez les annotations à l'aide de la clé font. Créez ensuite un objet Span personnalisé et remplacez l'objet Span existant.

    Kotlin

    // get the text as SpannedString so we can get the spans attached to the text
    val titleText = getText(R.string.title) as SpannedString
    
    // get all the annotation spans from the text
    val annotations = titleText.getSpans(0, titleText.length, Annotation::class.java)
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    val spannableString = SpannableString(titleText)
    
    // iterate through all the annotation spans
    for (annotation in annotations) {
       // look for the span with the key font
       if (annotation.key == "font") {
          val fontName = annotation.value
          // check the value associated to the annotation key
          if (fontName == "title_emphasis") {
             // create the typeface
             val typeface = getFontCompat(R.font.permanent_marker)
             // set the span at the same indices as the annotation
             spannableString.setSpan(CustomTypefaceSpan(typeface),
                titleText.getSpanStart(annotation),
                titleText.getSpanEnd(annotation),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
          }
       }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString
    

    Java

    // get the text as SpannedString so we can get the spans attached to the text
    SpannedString titleText = (SpannedString) getText(R.string.title);
    
    // get all the annotation spans from the text
    Annotation[] annotations = titleText.getSpans(0, titleText.length(), Annotation.class);
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    SpannableString spannableString = new SpannableString(titleText);
    
    // iterate through all the annotation spans
    for (Annotation annotation: annotations) {
      // look for the span with the key font
      if (annotation.getKey().equals("font")) {
        String fontName = annotation.getValue();
        // check the value associated to the annotation key
        if (fontName.equals("title_emphasis")) {
        // create the typeface
        Typeface typeface = ResourcesCompat.getFont(this, R.font.roboto_mono);
        // set the span at the same indices as the annotation
        spannableString.setSpan(new CustomTypefaceSpan(typeface),
          titleText.getSpanStart(annotation),
          titleText.getSpanEnd(annotation),
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString;
    

Si vous utilisez le même texte plusieurs fois, créez l'objet SpannableString une seule fois et réutilisez-le si nécessaire pour éviter les problèmes de performances et de mémoire potentiels.

Pour plus d'exemples d'utilisation des annotations, consultez Ajouter des styles à un texte internationalisé dans Android.

Objets Span d'annotation et morcellement de texte

Étant donné que les objets Span Annotation sont également définis sur ParcelableSpans, les paires clé/valeur sont dissociées et ne sont pas morcelées. Tant que le destinataire du morcellement sait comment interpréter les annotations, vous pouvez utiliser des objets Span Annotation pour appliquer un style personnalisé au texte morcelé.

Pour conserver votre style personnalisé lorsque vous transmettez le texte à un groupe d'intents, vous devez d'abord ajouter des objets Span Annotation au texte. Cela est possible dans les ressources XML via la balise <annotation>, comme indiqué dans l'exemple ci-dessus, ou dans le code en créant un objet Annotation et en le définissant en tant qu'objet Span, comme ci-dessous :

Kotlin

val spannableString = SpannableString("My spantastic text")
val annotation = Annotation("font", "title_emphasis")
spannableString.setSpan(annotation, 3, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

// start Activity with text with spans
val intent = Intent(this, MainActivity::class.java)
intent.putExtra(TEXT_EXTRA, spannableString)
startActivity(intent)

Java

SpannableString spannableString = new SpannableString("My spantastic text");
Annotation annotation = new Annotation("font", "title_emphasis");
spannableString.setSpan(annotation, 3, 7, 33);

// start Activity with text with spans
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(TEXT_EXTRA, spannableString);
this.startActivity(intent);

Récupérez le texte de l'élément Bundle en tant que SpannableString, puis analysez les annotations associées, comme illustré dans l'exemple ci-dessus.

Kotlin

// read text with Spans
val intentCharSequence = intent.getCharSequenceExtra(TEXT_EXTRA) as SpannableString

Java

// read text with Spans
SpannableString intentCharSequence = (SpannableString)intent.getCharSequenceExtra(TEXT_EXTRA);

Pour en savoir plus sur l'ajout de styles au texte, consultez les liens suivants :