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 :

String
Ressource XML qui fournit une seule chaîne.
Tableau de chaînes
Ressource XML qui fournit un tableau de 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 du code de l'application (par exemple, une fonction composable) ou d'autres fichiers de ressources.

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 Kotlin : 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 code d'application récupère une chaîne à l'intérieur d'un composable avec stringResource() :

@Composable
fun Greeting() {
    Text(text = stringResource(R.string.hello))
}

Remarque : Pour récupérer une chaîne en dehors d'une fonction composable, utilisez context.getString(R.string.hello).

Vous pouvez également référencer des ressources de chaîne à partir d'autres fichiers XML, tels que votre fichier AndroidManifest.xml :
<activity
    android:name=".MainActivity"
    android:label="@string/hello" />

Tableau de chaînes

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

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 Kotlin : 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 savoir comment styliser et mettre en forme correctement les chaînes, consultez 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 à l'intérieur d'un composable avec stringArrayResource() :

@Composable
fun PlanetList() {
    val planets: Array =
        stringArrayResource(R.array.planets_array)
    // Render the array, e.g. inside a LazyColumn.
}

Remarque : Pour récupérer un tableau de chaînes en dehors d'une fonction composable, utilisez context.resources.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 pluralStringResource() 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, une chaîne pour 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 anglais contient "a book" (un livre) et "many books" (plusieurs livres) sans le nombre réel, il peut être traduit par "knyga" (un livre)/"daug knygų" (plusieurs livres), mais avec les règles lituaniennes, il affichera "knyga" (un livre) lorsque le nombre est 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.

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 Kotlin : 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 savoir comment styliser et mettre en forme correctement les chaînes, consultez 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>

Ce code d'application récupère une chaîne au pluriel à partir d'un composable avec pluralStringResource() :

@Composable
fun SongCount(count: Int) {
    Text(
        text = pluralStringResource(
            R.plurals.numberOfSongsAvailable,
            count,
            count,
        )
    )
}

Lorsque vous utilisez la fonction pluralStringResource(), 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 à pluralStringResource.

Remarque : Pour récupérer une chaîne au pluriel en dehors d'une fonction composable, utilisez context.resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count).

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.

Personnage 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>).

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>

Ce code d'application met en forme la chaîne à partir d'un composable en transmettant des arguments directement dans stringResource() :

@Composable
fun WelcomeMessage(username: String, mailCount: Int) {
    Text(
        text = stringResource(
            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="…">

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 de mise en forme, telles que stringResource(), 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 AnnotatedString.fromHtml(), après la mise en forme. 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 AnnotatedString.fromHtml() pour convertir le texte HTML en chaîne Compose stylisée.

Étant donné que fromHtml() 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 TextUtils.htmlEncode().

import android.text.TextUtils
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.fromHtml

@Composable
fun WelcomeHtmlMessage(username: String, mailCount: Int) {
    // Escape the username in case it contains characters like "<" or "&"
    val escapedUsername = TextUtils.htmlEncode(username)

    val text = stringResource(
        R.string.welcome_messages,
        escapedUsername,
        mailCount,
    )

    Text(
        text = AnnotatedString.fromHtml(text)
    )
}

Ajouter des styles avec AnnotatedString

Un AnnotatedString est un objet texte Compose que vous pouvez styliser avec des propriétés telles que la couleur et l'épaisseur de la police. Créez du texte stylisé de manière programmatique à l'aide de buildAnnotatedString et withStyle.

Ce code d'application crée un seul élément de texte avec des styles mixtes :

@Composable
fun StyledGreeting() {
    val styled = buildAnnotatedString {
        append("Welcome to ")
        withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
            append("Android")
        }
        append("!")
    }
    Text(text = styled)
}

Pour appliquer la couleur, la taille de la police et la décoration du texte, utilisez SpanStyle. Pour appliquer un style au niveau du paragraphe (comme l'alignement ou la hauteur de ligne), utilisez ParagraphStyle :

@Composable
fun RichText() {
    val text = buildAnnotatedString {
        withStyle(ParagraphStyle(lineHeight = 24.sp, textAlign = TextAlign.Center)) {
            withStyle(SpanStyle(color = Color.Gray)) {
                append("Hello, ")
            }
            withStyle(
                SpanStyle(
                    fontWeight = FontWeight.Bold,
                    color = Color.Red,
                )
            ) {
                append("world")
            }
            append("!")
        }
    }
    Text(text = text)
}

La méthode recommandée pour les applications monolingues ou le texte statique dans Compose consiste à créer directement le AnnotatedString. Toutefois, pour le texte stylisé qui nécessite une localisation, consultez l'approche XML <annotation> détaillée dans la section suivante.

Mettre en forme des chaînes traduites avec des annotations

Pour les chaînes qui nécessitent une mise en forme et une traduction personnalisées, définissez la balise <annotation> dans le fichier strings.xml de chaque langue. Les traducteurs conservent l'annotation, quel que soit son emplacement dans la phrase. Lisez la chaîne avec context.resources.getText(), parcourez ses étendues Annotation et convertissez le résultat en AnnotatedString :

@Composable
fun AnnotatedTitle() {
    val context = LocalContext.current
    val source = context.resources.getText(R.string.title) as SpannedString
    val text = buildAnnotatedString {
        append(source.toString())
        source.getSpans(0, source.length, Annotation::class.java)
            .forEach { annotation ->
                if (annotation.key == "font" &&
                    annotation.value == "title_emphasis") {
                    addStyle(
                        SpanStyle(
                            fontFamily = FontFamily(
                                Font(R.font.permanent_marker)
                            )
                        ),
                        source.getSpanStart(annotation),
                        source.getSpanEnd(annotation),
                    )
                }
            }
    }
    Text(text = text)
}

La balise <annotation> de votre fichier XML reste inchangée. Seul le code de récupération diffère. Les traducteurs déplacent toujours la balise pour encadrer le mot correct dans chaque langue.

Ressources supplémentaires

Pour en savoir plus sur les ressources de chaîne, consultez les ressources supplémentaires suivantes :

Documentation

Afficher le contenu