Una risorsa stringa fornisce stringhe di testo per la tua applicazione con stile e formattazione del testo facoltativi. Esistono tre tipi di risorse che possono fornire stringhe alla tua applicazione:
- String
- Risorsa XML che fornisce una singola stringa.
- String Array
- Risorsa XML che fornisce un array di stringhe.
- Stringhe di quantità (plurali)
- Risorsa XML che contiene stringhe diverse per la pluralizzazione.
Tutte le stringhe sono in grado di applicare alcuni argomenti di formattazione e markup di stile. Per informazioni sulla formattazione e sullo stile delle stringhe, consulta la sezione Formattazione e stile.
Stringa
Una singola stringa a cui è possibile fare riferimento dal codice dell'applicazione (ad esempio una funzione componibile) o da altri file di risorse.
- posizione del file:
res/values/filename.xml
Il nome file è arbitrario. L'<string>dell'elementonameviene utilizzato come ID risorsa.- tipo di dati della risorsa compilata:
- Puntatore alla risorsa
String. - resource reference:
-
In Kotlin:
R.string.string_name
In XML:@string/string_name - sintassi:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
- elementi:
- esempio:
- File XML salvato in
res/values/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
Questo codice dell'applicazione recupera una stringa dall'interno di un elemento componibile con
stringResource():@Composable fun Greeting() { Text(text = stringResource(R.string.hello)) }
Nota:per recuperare una stringa al di fuori di una funzione componibile, utilizza
Puoi anche fare riferimento alle risorse stringa di altri file XML, ad esempiocontext.getString(R.string.hello).AndroidManifest.xml:<activity android:name=".MainActivity" android:label="@string/hello" />
Array di stringhe
Un array di stringhe a cui è possibile fare riferimento dall'applicazione.
- posizione del file:
res/values/filename.xml
Il nome file è arbitrario. L'<string-array>dell'elementonameviene utilizzato come ID risorsa.- tipo di dati della risorsa compilata:
- Puntatore di risorse a un array di
String. - resource reference:
-
In Kotlin:
R.array.string_array_name
In XML:@[package:]array/string_array_name - sintassi:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
- elementi:
- esempio:
- File XML salvato in
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>
Questo codice dell'applicazione recupera un array di stringhe dall'interno di un elemento componibile con
stringArrayResource():@Composable fun PlanetList() { val planets: Array
= stringArrayResource(R.array.planets_array) // Render the array, e.g. inside a LazyColumn. } Nota:per recuperare un array di stringhe al di fuori di una funzione componibile, utilizza
context.resources.getStringArray(R.array.planets_array).
Stringhe di quantità (plurali)
Lingue diverse hanno regole diverse per la concordanza grammaticale con
la quantità. In inglese, ad esempio, la quantità 1 è un caso speciale. Scriviamo
"1 libro", ma per qualsiasi altra quantità scriveremmo "n libri". Questa distinzione
tra singolare e plurale è molto comune, ma altre lingue fanno distinzioni
più sottili. Il set completo supportato da Android è zero, one, two, few,
many e other.
Le regole per decidere quale caso utilizzare per una determinata lingua e quantità possono
essere molto complesse, quindi Android ti fornisce metodi come
pluralStringResource() per selezionare la risorsa appropriata.
Sebbene storicamente siano chiamate "stringhe di quantità" (e lo siano ancora nell'API),
le stringhe di quantità devono essere utilizzate solo per i plurali. Sarebbe un errore
utilizzare le stringhe di quantità per implementare qualcosa come "Posta in arrivo" di Gmail rispetto a
"Posta in arrivo (12)" quando ci sono messaggi non letti, ad esempio. Potrebbe sembrare
comodo utilizzare stringhe di quantità anziché un'istruzione if, ma è
importante notare che alcune lingue (come il cinese) non fanno queste
distinzioni grammaticali, quindi otterrai sempre la stringa other.
La selezione della stringa da utilizzare si basa esclusivamente sulla necessità grammaticale. In inglese, una stringa per zero viene ignorata anche se la quantità è
0, perché 0 non è grammaticalmente diverso da 2 o da qualsiasi altro numero tranne 1
("zero books", "one book", "two books" e così via). Al contrario, in coreano
solo la stringa other viene utilizzata.
Non lasciarti ingannare dal fatto che, ad esempio, two sembra applicarsi solo alla quantità 2: una lingua potrebbe richiedere che 2, 12, 102 (e così via) vengano trattati allo stesso modo, ma in modo diverso rispetto ad altre quantità. Affidati al tuo
traduttore per sapere quali distinzioni richiede la sua lingua.
Se il messaggio non contiene il numero di quantità, probabilmente non è un buon candidato per un plurale. Ad esempio, in lituano la forma singolare viene utilizzata sia per 1 che per 101, quindi "1 libro" viene tradotto come "1 knyga" e "101 libri" come "101 knyga". Nel frattempo, "un libro" è "knyga" e "molti libri" è "daug knygų". Se un messaggio plurale in inglese contiene "a book" (singolare) e "many books" (plurale) senza il numero effettivo, può essere tradotto come "knyga" (un libro)/"daug knygų" (molti libri), ma con le regole lituane, verrà visualizzato "knyga" (un libro singolo) quando il numero è 101.
Spesso è possibile evitare le stringhe di quantità utilizzando formulazioni neutre rispetto alla quantità, ad esempio "Libri: 1". In questo modo, la tua vita e quella dei tuoi traduttori saranno più semplici, se si tratta di uno stile accettabile per la tua applicazione.
Sulle API 24 e successive puoi utilizzare la classe ICU MessageFormat, molto più potente.
- posizione del file:
res/values/filename.xml
Il nome file è arbitrario. L'<plurals>dell'elementonameviene utilizzato come ID risorsa.- resource reference:
-
In Kotlin:
R.plurals.plural_name - sintassi:
-
<?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>
- elementi:
- esempio:
File XML salvato in
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>
File XML salvato in
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>
Questo codice dell'applicazione recupera una stringa plurale dall'interno di un composable con
pluralStringResource():@Composable fun SongCount(count: Int) { Text( text = pluralStringResource( R.plurals.numberOfSongsAvailable, count, count, ) ) }
Quando utilizzi la funzione
pluralStringResource(), devi passarecountdue volte se la stringa include la formattazione della stringa con un numero. Ad esempio, per la stringa%d songs found, il primo parametrocountseleziona la stringa plurale appropriata e il secondo parametrocountviene inserito nel segnaposto%d. Se le stringhe plurali non includono la formattazione delle stringhe, non devi passare il terzo parametro apluralStringResource.Nota:per recuperare una stringa plurale al di fuori di una funzione componibile, utilizza
context.resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count).
Formato e stile
Ecco alcune informazioni importanti su come formattare e stilizzare correttamente le risorse stringa.
Gestire i caratteri speciali
Quando una stringa contiene caratteri con un utilizzo speciale in XML, devi utilizzare il codice di escape per i caratteri in base alle regole standard di escape XML/HTML. Se devi eseguire l'escape di un carattere che ha un significato speciale in Android, devi utilizzare una barra rovesciata precedente.
Per impostazione predefinita, Android comprime le sequenze di caratteri di spazio vuoto in un unico spazio. Per evitare questo problema, racchiudi la parte pertinente della stringa tra virgolette doppie. In questo caso, tutti i caratteri di spazio vuoto (incluse le nuove righe) verranno conservati all'interno della regione tra virgolette. Le virgolette doppie ti consentono di utilizzare anche virgolette singole normali senza caratteri di escape.
| Carattere | Form(s) escaped |
|---|---|
| @ | \@ |
| ? | \? |
| Nuova riga | \n |
| Tab | \t |
| Carattere Unicode U+XXXX | \uXXXX |
Virgoletta singola (') |
Uno dei seguenti:
|
Virgolette doppie (") |
\"
Tieni presente che racchiudere la stringa tra virgolette singole non funziona. |
La compressione degli spazi bianchi e l'escape di Android vengono eseguiti dopo l'analisi del file di risorse
come XML. Ciò significa che <string>      </string>
(spazio, spazio di punteggiatura, spazio Unicode Em) si riducono a un unico spazio
(" "), perché sono tutti spazi Unicode dopo l'analisi del file come XML.
Per preservare questi spazi così come sono, puoi racchiuderli tra virgolette
(<string>"      "</string>)
o utilizzare l'escape di Android
(<string> \u0032 \u8200 \u8195</string>).
Stringhe di formattazione
Se devi formattare le stringhe, puoi farlo inserendo gli argomenti di formattazione nella risorsa stringa, come mostrato nell'esempio di risorsa seguente.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Questo codice dell'applicazione formatta la stringa dall'interno di un elemento componibile passando
gli argomenti direttamente a stringResource():
@Composable fun WelcomeMessage(username: String, mailCount: Int) { Text( text = stringResource( R.string.welcome_messages, username, mailCount, ) ) }
Applicare stili con il markup HTML
Puoi aggiungere uno stile alle stringhe con il markup HTML. Ad esempio:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Sono supportati i seguenti elementi HTML:
- Grassetto:
<b> - Corsivo:
<i>,<cite>,<dfn>,<em> - Testo più grande del 25%:
<big> - Testo più piccolo del 20%:
<small> - Impostazione delle proprietà del carattere:
<font face="font_family" color="hex_color">. Esempi di possibili famiglie di caratteri includonomonospace,serifesans_serif. - Impostazione di una famiglia di caratteri monospazio:
<tt> - Barrato:
<s>,<strike>,<del> - Sottolineato:
<u> - Apice:
<sup> - Pedice:
<sub> - Elenco puntato:
<ul>,<li> - Interruzioni di riga:
<br> - Divisione:
<div> - Stile CSS:
<span style="color|background_color|text-decoration"> - Paragrafi:
<p dir="rtl | ltr" style="…">
In alcuni casi, potresti voler creare una risorsa di testo con stile che venga utilizzata anche
come stringa di formato. Normalmente, questo non funziona perché i metodi di formattazione,
come stringResource(), rimuovono tutte le informazioni di stile dalla stringa.
La soluzione alternativa consiste nello scrivere i tag HTML con entità di escape, che
vengono poi recuperate con AnnotatedString.fromHtml(), dopo la formattazione. Ad esempio:
- Memorizza la risorsa di testo con stile come stringa con escape HTML:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
In questa stringa formattata viene aggiunto un elemento
<b>. Nota che la parentesi aperta è codificata in HTML utilizzando la notazione<. - Quindi, formatta la stringa come di consueto, ma chiama anche
AnnotatedString.fromHtml()per convertire il testo HTML in una stringa di composizione con stile.
Poiché fromHtml() formatta tutte le entità HTML, assicurati di eseguire l'escape di tutti i possibili caratteri HTML nelle stringhe che utilizzi con il testo formattato, utilizzando 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) ) }
Stile con AnnotatedString
Un AnnotatedString è un oggetto di testo di Compose che puoi stilizzare con proprietà come colore e spessore del carattere. Crea testo con stile a livello di programmazione
utilizzando buildAnnotatedString e withStyle.
Questo codice dell'applicazione crea un singolo elemento di testo con stili misti:
@Composable fun StyledGreeting() { val styled = buildAnnotatedString { append("Welcome to ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Android") } append("!") } Text(text = styled) }
Per applicare colore, dimensione del carattere e decorazione del testo, utilizza SpanStyle. Per applicare
uno stile a livello di paragrafo (ad esempio allineamento o altezza riga), utilizza 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 creazione di AnnotatedString direttamente è l'approccio consigliato per
app in una sola lingua o testo statico in Compose. Tuttavia, per il testo formattato che
richiede la localizzazione, consulta l'approccio XML <annotation> descritto nella sezione
successiva.
Applicare stili alle stringhe tradotte con annotazioni
Per le stringhe che richiedono uno stile personalizzato e la traduzione, definisci il tag
<annotation> nel file strings.xml di ogni impostazione internazionale. I traduttori mantengono
l'annotazione indipendentemente dalla sua posizione nella frase. Leggi la stringa con
context.resources.getText(), percorri gli intervalli Annotation e converti
il risultato in un 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) }
Il tag <annotation> nel tuo XML è invariato. Solo il codice di recupero
è diverso. I traduttori spostano comunque il tag per racchiudere la parola corretta in ogni
lingua.
Risorse aggiuntive
Per saperne di più sulle risorse stringa, consulta le seguenti risorse aggiuntive: