È possibile aggiungere dinamicamente String a String.xml in Android?


Risposte:


1035

Formattazione e styling

Sì, vedere quanto segue da Risorse stringa: Formattazione e stile

Se è necessario formattare le stringhe utilizzando String.format(String, Object...), è possibile farlo inserendo gli argomenti del formato nella risorsa stringa. Ad esempio, con la seguente risorsa:

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

In questo esempio, la stringa di formato ha due argomenti: %1$sè una stringa ed %2$dè un numero decimale. Puoi formattare la stringa con argomenti della tua applicazione in questo modo:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

Utilizzo di base

Si noti che getStringha un sovraccarico che utilizza la stringa come stringa di formato:

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

plurali

Se devi gestire i plurali, usa questo:

<plurals name="welcome_messages">
    <item quantity="one">Hello, %1$s! You have a new message.</item>
    <item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>

Il primo mailCountparametro viene utilizzato per decidere quale formato utilizzare (singolo o plurale), gli altri parametri sono le sostituzioni:

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

Vedi Risorse sulle stringhe: plurali per maggiori dettagli.


61
La chiamata String.format nel primo esempio di codice non è effettivamente necessaria, Resources.getString () supporta la formattazione, consultare: developer.android.com/reference/android/content/res/… , java.lang.Object ...)
Arnaud,

16
per Plurali in String.xml devi dare id come R.plurals.welcome_messages invece di R.string.welcome_messages
om252345

cosa plurale che restituisce solo la stringa dell'ultimo elemento ... qualsiasi idea su come ottenere la stringa di aggiunta.
CoDe

1
Quando si utilizza questo metodo per formattare la stringa, vengono rimossi tutti i metatag che è possibile aver utilizzato come collegamenti ipertestuali ecc. Che potrebbero essere stati contenuti nel testo della stringa xml
Jonathan

4
String sta per% 1 $ s, decimale per% 2 $ d e numero intero sta per cosa? qual è il significato% 1,% 2. È questo conteggio del parametro?. Se voglio il terzo parametro È menzionato% 3?
reegan29,

260

Risposta supplementare

Quando ho visto per la prima volta %1$se %2$dnella risposta accettata, non aveva senso. Ecco una spiegazione in più.

Sono chiamati identificatori di formato. Nella stringa xml sono nella forma di

%[parameter_index$][format_type] 
  • % : Il segno di percentuale segna l'inizio dell'identificatore di formato.
  • indice parametri : questo è un numero seguito da un segno di dollaro. Se tu avessi tre parametri che si voleva inserire nella stringa, allora sarebbero stati chiamati 1$, 2$e 3$. L'ordine in cui vengono inseriti nella stringa di risorse non ha importanza, ma solo l'ordine in cui vengono forniti i parametri.
  • tipo di formato : ci sono molti modi in cui puoi formattare le cose ( vedi la documentazione ). Eccone alcuni comuni:

    • s corda
    • d numero intero decimale
    • f numero in virgola mobile

Esempio

Creeremo la seguente stringa formattata in cui le parti grigie vengono inserite a livello di codice.

Mia sorella Maryè 12anni.

string.xml

<string name="my_xml_string">My sister %1$s is %2$d years old.</string>

MyActivity.java

String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);

Appunti

  • Potrei usare getStringperché ero in un'attività. È possibile utilizzare context.getResources().getString(...)se non è disponibile.
  • String.format() formatterà anche una stringa.
  • I termini 1$e 2$non devono essere usati in quell'ordine. Cioè, 2$può venire prima 1$. Ciò è utile quando si internazionalizza un'app per lingue che usano un diverso ordine di parole.
  • È possibile utilizzare un identificatore di formato come %1$spiù volte nel file XML se si desidera ripeterlo.
  • Utilizzare %%per ottenere il %personaggio reale .
  • Per maggiori dettagli leggi il seguente tutorial utile: Android SDK Suggerimento rapido: formattazione delle stringhe di risorse

125

Quando si desidera utilizzare un parametro dal file strings.xml effettivo senza utilizzare alcun codice Java:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "WhereDat">
  <!ENTITY author "Oded">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

Questo non funziona su tutti i file di risorse, ovvero le variabili devono essere copiate in ogni file XML che ne ha bisogno.


Questa è una buona risposta tranne quando hai un parametro dentro <! [CDATA [& param; ]]>
Hermann Poilpre,

2
Esiste un modo per definire la <!DOCTYPE... ]>parte in un file separato e includerla in più file di risorse? Qualche trucco per raggiungere questo obiettivo?
prom85,

18

Stava cercando lo stesso e finalmente ho trovato la seguente soluzione molto semplice. Migliore: funziona fuori dagli schemi.
1. modifica la tua risorsa di stringa:

<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have 
<xliff:g name="count">%d</xliff:g> new messages.</string>

2. usa la sostituzione di stringa:

c.getString(R.string.welcome_messages,name,count);

dove c è il contesto, name è una variabile stringa e conta la variabile int

Dovrai includere

<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

nel tuo res / strings.xml. Per me va bene. :)


2
Qual è il punto dei xlifftag attorno agli identificatori di formato? Quale valore aggiunto aggiungono invece di usare da soli gli specificatori %se %d?
Richard Le Mesurier,

L'attributo "name" nel tag xliff è solo un modo per dare un suggerimento al traduttore su ciò che verrà sostituito al suo interno. A volte non è facile indovinare cosa significa "% s".
hugomg,

3

In Kotlin devi solo impostare il valore della stringa in questo modo:

<string name="song_number_and_title">"%1$d ~ %2$s"</string>

Crea una vista di testo sul layout:

<TextView android:id="@+id/song_number_and_title"/>

Quindi fai questo nel tuo codice se stai usando Anko:

val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))  

Potrebbe essere necessario recuperare le risorse dal contesto dell'applicazione.


5
In che modo differisce dagli esempi di Java? Non vedo alcuna differenza
Janusz Hain il


1

in res / valori / stringa.xml

<resources>
    <string name="app_name">Hello World</string>
    <string name="my_application">Application name: %s, package name: %s</string>
</resources>

nel codice java

String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);


1

Se vuoi scrivere percent (%), duplicalo:

<string name="percent">%1$d%%</string>

label.text = getString(R.string.percent, 75) // Output: 75%.

Se si scrive semplicemente %1$d%, si otterrà l'errore: Format string 'percent' is not a valid format string so it should not be passed to String.format.


0

Sì! puoi farlo senza scrivere alcun codice Java / Kotlin, solo XML usando questa piccola libreria che ho creato, che lo fa in fase di compilazione, quindi la tua app non ne sarà influenzata: https://github.com/LikeTheSalad/android -String riferimento

uso

Le tue corde:

<resources>
    <string name="app_name">My App Name</string>
    <string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>

La stringa generata dopo la creazione:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

0

Una soluzione Kotlin diretta al problema:

strings.xml

<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>

kotlinActivityORFragmentFile.kt:

val username = "Andrew"
val products = 1000
val text: String = String.format(
      resources.getString(R.string.customer_message), username, products )

0

Nel tuo file di stringa usa questo

<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>

E nel tuo codice usa come di conseguenza

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));

-1

Versione di Kotlin della risposta accettata ...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

3
Il modo più corretto è utilizzare il resources.getString(int, ... args)metodo con argomenti anziché String.format. Non ci sono neanche specifiche di kotlin in questo codice, tranne la valparola chiave. Vedi la risposta di msbodw001
dant3,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.