2010-12-11 5 views
239

J'ai un tableau de chaînes dans lequel le symbole % est utilisé. Le bon format pour utiliser le % est %. Quand j'ai une chaîne dans ce tableau avec plusieurs % il me donne cette erreur.Symbole de pourcentage XML Android

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 
+3

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

+0

Il s'agit d'une erreur qui peut facilement être répliquée par n'importe quelle chaîne avec 2 symboles ou plus. – zaid

+0

Si vous ne cherchez pas un but de formatage, mieux [way] (http://stackoverflow.com/a/9813801/2365197) accomplir. –

Répondre

402

L'outil Asset emballage Android (aapt) est devenu very strict in its latest release et est maintenant utilisé pour toutes versions Android. L'erreur aapt que vous obtenez est générée car elle n'autorise plus non-positional format specifiers.

Voici quelques idées pour inclure le symbole% dans vos chaînes de ressources.

Si vous ne avez pas besoin de spécificateurs de format ou des substitutions dans votre chaîne, vous pouvez simplement utiliser l'attribut formatted et le mettre à false:

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

Dans ce cas, la chaîne n'est pas utilisé comme chaîne de format pour le Formatter afin que vous n'ayez pas à échapper votre% -symbols. La chaîne résultante est "% a +% a == 2% a".

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

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

maintenant aapt vous donne pas d'erreur, mais selon la façon dont vous l'utilisez, la chaîne résultante peut être « %% a + %% a == 2 %% un » si un Formatter est invoqué sans format arguments:

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 xml et le code, il est difficile de dire exactement ce que votre problème est, mais nous espérons que cela vous aide à comprendre les mécanismes un peu mieux.

+1

J'ai choisi ceci comme réponse parce que cela devrait fonctionner, mais apparemment il y a un bogue qui se trouve dans cette chaîne, donc j'ai décidé d'utiliser %% et "XXX.replaceAll (" %% " , "%"); " – zaid

+3

en utilisant ** formatted = false ** fonctionne bien. Voici comment je l'ai utilisé: \ 'Sweet \' 10% à 20% même 35% de sucre en poids

+1

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

-13

Essayez d'utiliser une barre oblique inverse devant elle, comme ci-dessous:

\% 
+0

Même erreur que précédemment. – zaid

+3

cela devrait être \ %% – JustCurious

147

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

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

doit être remplacé par

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

Vous pouvez voir this pour plus de détails.

+2

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

+22

Pour la substitution de plusieurs paramètres (par exemple avec des chaînes), utilisez '% 1 $ s','% 2 $ s' etc – CJBS

+1

qui lira une réponse si grande pour cette petite chose? Merci, je défile vers le bas pour vous trouver. –

4

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 un émulateur, ou même sur des périphériques, il peut apparaître comme %%. – samwize

38

Vous pouvez échapper% en utilisant %% pour l'analyseur XML, mais s'affiche deux fois dans le périphérique.

Pour montré une fois essayer d'utiliser ce format \ %% par exemple

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

est présentée comme Fat Burning (50% à 60%) dans le dispositif

+4

\ %% provoque des plantages sur le Nexus 4 4.2.1. N'ont pas testé les autres. –

+0

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 formatage de chaînes et que vous devez toujours définir ces valeurs codées en dur par programmation. – portfoliobuilder

+0

Cela s'est écrasé pour moi aussi bien sur Nexus 5.1.1. @ViliusK réponse est la bonne. –

3

Essayez celui-ci (à droite):

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

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

Par exemple, le nombre Unicode pour signe pour cent est 0025:

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

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

+1

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

+0

Le fichier de ressources est converti en une ressource Java et, ce faisant, le caractère '%' est renvoyé. J'ai peur que cela ne résout pas le problème. –

+0

http://stackoverflow.com/a/3061297/1787135 – jpardogo

5

Cela pourrait être un cas de l'IDE devient trop stricte. L'idée est bonne, en général, vous devriez spécifier l'ordre des variables de substitution de sorte que si vous ajoutez des ressources pour une autre langue, votre code java n'aura pas besoin d'être changé. Cependant, il y a deux problèmes avec ceci:

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

You will need %.5G %s 

à utiliser comme Vous aurez besoin 2,1200 mg aura l'ordre même dans toutes les langues que ce montant de la masse est toujours représentée dans cet ordre scientifiquement. La seconde est que si vous mettez l'ordre des variables dans quelle langue vos ressources par défaut sont spécifiées (par exemple en anglais), vous n'avez qu'à spécifier les positions dans les chaînes de ressources pour les langues que vous utilisez dans un ordre différent. langage par défaut.

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

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

18

Utilisez

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

pour obtenir

80% wins comme mis en forme chaîne. J'utilise la méthode String.format() pour obtenir le numéro inséré au lieu de %d.

3

Une méthode délicate: en utilisant signe petit pour cent en dessous

<string name="zone_50">Fat Burning (50&#65130; to 60&#65130;)</string> 

Percent Sign on Wikipedia

4

pour échapper le symbole pour cent, vous avez juste besoin %%

par exemple:

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

retours "10%"

+1

Votre réponse est à peu près la même que plusieurs autres réponses existantes –

+0

... et faux, car renvoie «10%» pas «% 10». FIY: Lorsque vous utilisez 'String.format', vous devez toujours spécifier Locale. Vous pouvez être vraiment surpris quand vous ne mettez pas Locale et n'utilisez pas les paramètres régionaux en arabe pour les numéros de format ... – mtrakal

+0

merci @mtrakal pour les conseils sur les paramètres régionaux ~ – landerlyoung

5

Pas exactement votre problème, mais un semblable.

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

NE PAS:

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

DO:

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

Supposons que vous voulez afficher (50% OFF) et entrez 50 lors 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 l'utilisation de classe Java ce code:

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