Est-il possible d'avoir des espaces réservés dans des valeurs de chaîne dans string.xml
lesquelles des valeurs peuvent être affectées au moment de l'exécution?
Exemple:
de la chaîne PLACEHOLDER1 de la chaîne
Est-il possible d'avoir des espaces réservés dans des valeurs de chaîne dans string.xml
lesquelles des valeurs peuvent être affectées au moment de l'exécution?
Exemple:
de la chaîne PLACEHOLDER1 de la chaîne
Réponses:
Oui, voir ce qui suit dans String Resources: Formating and Styling
Si vous devez formater vos chaînes à l'aide de
String.format(String, Object...)
, vous pouvez le faire en plaçant vos arguments de format dans la ressource de chaîne. Par exemple, avec la ressource suivante:<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Dans cet exemple, la chaîne de format a deux arguments:
%1$s
est une chaîne et%2$d
est un nombre décimal. Vous pouvez formater la chaîne avec des arguments de votre application comme ceci:Resources res = getResources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
Notez qu'il y getString
a une surcharge qui utilise la chaîne comme chaîne de format:
String text = res.getString(R.string.welcome_messages, username, mailCount);
Si vous devez gérer des pluriels, utilisez ceci:
<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>
Le premier mailCount
paramètre est utilisé pour décider du format à utiliser (simple ou pluriel), les autres paramètres sont vos substitutions:
Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);
Voir String Resources: Plurals pour plus de détails.
Quand j'ai vu pour la première fois %1$s
et %2$d
dans la réponse acceptée, cela n'avait aucun sens. Voici un peu plus d'explication.
Ils sont appelés spécificateurs de format. Dans la chaîne xml, ils se présentent sous la forme de
%[parameter_index$][format_type]
1$
, 2$
et 3$
. L'ordre dans lequel vous les placez dans la chaîne de ressources n'a pas d'importance, seul l'ordre dans lequel vous fournissez les paramètres.type de format : Il existe de nombreuses façons de formater des éléments ( voir la documentation ). Voici quelques exemples courants:
s
chaîned
entier décimalf
nombre à virgule flottanteNous allons créer la chaîne formatée suivante où les parties grises sont insérées par programme.
Ma soeur
Mary
est12
ans.
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);
getString
parce que j'étais dans une activité. Vous pouvez l'utiliser context.getResources().getString(...)
s'il n'est pas disponible.String.format()
formatera également une chaîne.1$
et 2$
n'ont pas besoin d'être utilisés dans cet ordre. Autrement dit, 2$
peut venir avant1$
. Cela est utile lors de l'internationalisation d'une application pour les langues qui utilisent un ordre de mots différent.%1$s
plusieurs fois dans le xml si vous souhaitez le répéter.%%
pour obtenir le réel%
personnage .Lorsque vous souhaitez utiliser un paramètre du fichier strings.xml réel sans utiliser de code 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>
Cela ne fonctionne pas entre les fichiers de ressources, c'est-à-dire que les variables doivent être copiées dans chaque fichier XML qui en a besoin.
<!DOCTYPE... ]>
pièce dans un fichier séparé et de l'inclure dans plusieurs fichiers de ressources? Une astuce pour y parvenir?
Cherchait la même chose et a finalement trouvé la solution très simple suivante. Meilleur: cela fonctionne hors de la boîte.
1. modifiez votre ressource de chaîne:
<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. utilisez la substitution de chaîne:
c.getString(R.string.welcome_messages,name,count);
où c est le contexte, le nom est une variable chaîne et comptez votre variable int
Vous devrez inclure
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">
dans votre res / strings.xml. Travaille pour moi. :)
xliff
servent les balises autour des spécificateurs de format? Quelle valeur ajoutée ajoutent-ils au lieu d'utiliser uniquement les spécificateurs %s
et %d
?
Dans Kotlin, il vous suffit de définir la valeur de votre chaîne comme ceci:
<string name="song_number_and_title">"%1$d ~ %2$s"</string>
Créez une vue texte sur votre mise en page:
<TextView android:id="@+id/song_number_and_title"/>
Ensuite, faites cela dans votre code si vous utilisez 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))
Vous devrez peut-être obtenir vos ressources à partir du contexte de l'application.
Cependant, vous devriez également lire la réponse d' Elias Mårtenson sur le traitement des pluriels Android de «zéro» . Il y a un problème avec l'interprétation de certaines valeurs telles que "zéro".
dans res / values / string.xml
<resources>
<string name="app_name">Hello World</string>
<string name="my_application">Application name: %s, package name: %s</string>
</resources>
en code 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);
Vous pouvez utiliser MessageFormat
:
<string name="customer_address">Wellcome: {0} {1}</string>
En code Java:
String text = MessageFormat(R.string.customer_address).format("Name","Family");
API niveau 1:
https://developer.android.com/reference/java/text/MessageFormat.html
Si vous voulez écrire le pourcentage (%), dupliquez-le:
<string name="percent">%1$d%%</string>
label.text = getString(R.string.percent, 75) // Output: 75%.
Si vous écrivez simplement %1$d%
, vous obtiendrez l'erreur: Format string 'percent' is not a valid format string so it should not be passed to String.format
.
Oui! vous pouvez le faire sans écrire de code Java / Kotlin, uniquement XML en utilisant cette petite bibliothèque que j'ai créée, qui le fait au moment de la construction, de sorte que votre application ne sera pas affectée par celle-ci: https://github.com/LikeTheSalad/android -string-reference
Usage
Vos cordes:
<resources>
<string name="app_name">My App Name</string>
<string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>
La chaîne générée après la construction:
<!--resolved.xml-->
<resources>
<string name="welcome_message">Welcome to My App Name</string>
</resources>
Une solution directe de Kotlin au problème:
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 )
Dans votre fichier de chaîne, utilisez ceci
<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>
Et dans votre code, utilisez en conséquence
coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
, rewardPoints.getConversion_rate(), getString(R.string.rs)));
Version Kotlin de la réponse acceptée ...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
resources.getString(int, ... args)
méthode avec des arguments au lieu de String.format
. Il n'y a pas non plus de spécificité kotlin dans ce code, autre que val
mot clé. Voir la réponse de msbodw001