È 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.