Symbole de pourcentage XML Android


309

J'ai un tableau de chaînes dans lequel le %symbole est utilisé. Format approprié pour l'utilisation de l' %is %. Lorsque j'ai une chaîne dans ce tableau avec plusieurs, %cela me donne cette erreur.

 Multiple annotations found at this
 line:
 - error: Multiple substitutions specified in non-positional format;
   did you mean to add the formatted="false" attribute?
 - error: Found tag </item> where </string-array> is expected

6
Pouvez-vous publier le code XML à l'origine de cette erreur? Il peut être très difficile d'identifier un problème sans en voir la cause.
Chris Cashwell

c'est une erreur qui peut facilement être répliquée par n'importe quelle chaîne avec 2 symboles% ou plus.
zaid

Si vous ne cherchez pas à des fins de formatage, une meilleure façon d'accomplir.
Shishir Gupta

Dans mon cas, j'ai entré à tort le paramètre de formatage comme 1% $ s, au lieu de% 1 $ s.
Ashokchakravarthi Nagarajan

Réponses:


467

L'outil Android Asset Packaging Tool ( aapt) est devenu très strict dans sa dernière version et est maintenant utilisé pour toutes les versions d'Android. L'erreur aapt que vous obtenez est générée car elle n'autorise plus les spécificateurs de format non positionnels .

Voici quelques idées sur la façon dont vous pouvez inclure le symbole% dans vos chaînes de ressources.

Si vous n'avez pas besoin de spécificateurs de format ou de substitutions dans votre chaîne, vous pouvez simplement utiliser l' formattedattribut et le définir sur false:

<string formatted="false">%a + %a == 2%a</string>

Dans ce cas, la chaîne n'est pas utilisée comme chaîne de format pour le Formatterafin que vous n'ayez pas à échapper à vos symboles%. La chaîne résultante est "% a +% a == 2% a".

Si vous omettez l' formatted="false"attribut, la chaîne est utilisée comme chaîne de format et vous devez échapper aux symboles%. Cela se fait correctement avec double-%:

<string>%%a + %%a == 2%%a</string>

aaptNe vous donne maintenant aucune erreur mais selon la façon dont vous l'utilisez, la chaîne résultante peut être "%% a + %% a == 2 %% a" si a Formatterest invoqué sans aucun argument de format :

Resources res = context.getResources();

String s1 = res.getString(R.string.str);
// s1 == "%%a + %%a == 2%%a"

String s2 = res.getString(R.string.str, null);
// s2 == "%a + %a == 2%a"

Sans aucun XML et code, il est difficile de dire quel est exactement votre problème, mais j'espère que cela vous aidera à mieux comprendre les mécanismes.


1
J'ai sélectionné cela comme réponse car cela devrait fonctionner, mais apparemment il y a un bogue dans lequel je suis en train de tomber avec cette chaîne, alors j'ai décidé d'utiliser %% et "XXX.replaceAll (" %% ","% ");"
zaid

4
utiliser formaté = faux fonctionne bien. Voici comment je l'ai utilisé: <string name = "information_description" formated = "false"> \ 'Sweet \' 10% à 20% voire 35% de sucre en poids </string>
Someone Somewhere

1
formaté = faux fonctionne bien pour moi aussi. En utilisant %%, il est littéralement apparu comme %% sur mon appareil et mon émulateur ..
samwize

formaté = faux a bien fonctionné pour moi dans le passé. maintenant (ADT 22), pour une raison quelconque, ce n'est pas le cas. et si j'utilise: "str = mContext.getString (R.string.str," bonjour ")", il aura cet avertissement: "La chaîne de format 'str' n'est pas une chaîne de format valide, elle ne doit donc pas être transmise à String.format "
développeur Android

1
Si vous accédez à partir de <string-array />, alors pour imprimer le pourcentage, utilisez \ u0025. Cela a fonctionné pour moi.
Chintan Shah

157

Pour autoriser l'application à utiliser des chaînes formatées à partir de ressources, vous devez corriger votre XML. Ainsi, par exemple

<string name="app_name">Your App name, ver.%d</string>

devrait être remplacé par

<string name="app_name">Your App name, ver.%1$d</string>

Vous pouvez voir ce pour plus de détails.


2
Merci, vous avez fourni le lien manquant - littéralement.
akauppi

22
Pour la substitution de paramètres multiples (par exemple avec des chaînes), utilisez %1$s, %2$setc.
CJBS

1
qui lira une si grosse réponse pour cette petite chose? Merci, je défile vers le bas pour vous trouver.
Janaka R Rajapaksha

73

Vous pouvez échapper% en utilisant %% pour l'analyseur XML, mais il est affiché deux fois dans l'appareil.

Pour l'afficher une fois, essayez le format suivant: \%%

Par exemple

<string name="zone_50">Fat Burning (50\%% to 60\%%)</string> 

est affiché comme Fat Burning (50% to 60%)dans l'appareil


6
\ %% provoque des plantages sur Nexus 4 4.2.1. N'en ai pas testé d'autres.
Jon Willis

Cela fonctionne bien et est facile lorsque vous connaissez déjà le pourcentage que vous souhaitez inclure dans vos chaînes, par rapport à l'utilisation du formateur de chaînes et en devant toujours définir ces valeurs codées en dur par programme.
portfoliobuilder

Cela s'est également écrasé pour moi sur Nexus 5.1.1. La réponse @ViliusK est la bonne.
Chan Jing Hong

2
utilisez simplement %% au lieu de%
Sundeep1501

37

Utilisation

<string name="win_percentage">%d%% wins</string>

obtenir

80% wins comme une chaîne formatée.

J'utilise la String.format()méthode pour obtenir le nombre inséré au lieu de %d.


12

Dans votre fichier strings.xml, vous pouvez utiliser n'importe quel signe Unicode de votre choix.

Par exemple, le nombre Unicode pour le signe de pourcentage est 0025:

<string name="percent_sign">&#x0025;</string>

Vous pouvez voir une liste complète des signes Unicode ici


1
Ça n'a aucun sens. & # x0025; et% sont identiques dans un fichier xml.
BeniBela

Le fichier de ressources est converti en ressource Java et, ce faisant, le %caractère revient. Je crains que cela ne résout pas le problème.
Paul Lammertsma

9

pour échapper au symbole de pourcentage, vous avez juste besoin de %%

par exemple :

String.format("%1$d%%", 10)

renvoie "10%"


1
Votre réponse est à peu près la même que plusieurs autres réponses existantes
Ben Rhys-Lewis

... et faux, car 10%ne revient pas %10. FIY: Lorsque vous utilisez, String.formatvous devez à chaque fois spécifier Locale. Vous pouvez être vraiment surpris lorsque vous ne mettez pas les paramètres régionaux et n'utilisez pas les paramètres régionaux arabes pour les numéros de format ...
mtrakal

7

Pas exactement votre problème, mais un problème similaire.

Si vous avez plusieurs formats dans votre entrée de chaîne, vous ne devez pas utiliser "% s" plusieurs fois.

NE PAS:

<string name="entry">Planned time %s - %s (%s)</string>

FAIRE :

<string name="entry">Planned time %1$s - %2$s (%3$s)</string>

5

Vous pouvez échapper le% en xml avec %%, mais vous devez définir le texte dans le code, pas dans la mise en page xml.


1
Oui, il s'échappe avec double% et compile bien. Mais lorsqu'il est exécuté sur l'émulateur, ou même sur des appareils, il peut apparaître sous la forme %%.
samwize

5

Cela pourrait être un cas où l'IDE deviendrait trop strict.

L'idée est bonne, en général, vous devez spécifier l'ordre des variables de substitution afin que si vous ajoutez des ressources pour une autre langue, votre code java n'aura pas besoin d'être modifié. Cependant, cela pose deux problèmes:

Tout d'abord, une chaîne telle que:

You will need %.5G %s

à utiliser car vous aurez besoin de 2.1200 mg aura l'ordre le même dans n'importe quelle langue car cette quantité de masse est toujours représentée scientifiquement dans cet ordre.

La seconde est que si vous placez l'ordre des variables dans la langue dans laquelle vos ressources par défaut sont spécifiées (par exemple en anglais), il vous suffit de spécifier les positions dans les chaînes de ressources pour les langues et d'utiliser un ordre différent de votre langue par défaut.

La bonne nouvelle est que c'est simple à corriger. Même s'il n'est pas nécessaire de spécifier les positions et que l'IDE est trop strict, spécifiez-les quand même. Pour l'exemple ci-dessus, utilisez:

Vous aurez besoin de% 1 $ .5G% 2 $ s



3

Essayez celui-ci (à droite):

<string name="content" formatted="false">Great application %s  ☞  %s  ☞  %s \\n\\nGo to download this application %s</string>


-1

Supposons que vous souhaitiez afficher (50% de réduction) et saisir 50 au moment de l'exécution. Voici le code:

<string name="format_discount"> (
<xliff:g id="discount">%1$s</xliff:g>
<xliff:g id="percentage_sign">%2$s</xliff:g>
 OFF)</string>

Dans la classe java, utilisez ce code:

String formattedString=String.format(context.getString(R.string.format_discount),discountString,"%");
holder1.mTextViewDiscount.setText(formattedString);

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.