Símbolo de porcentaje de Android XML

309

Tengo una serie de cadenas en las que %se usa el símbolo. Formato adecuado para usar el %is %. Cuando tengo una cadena en esa matriz con múltiples %, me da este error.

 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
zaid
fuente
66
¿Puedes publicar el XML que está causando este error? Puede ser muy difícil identificar un problema sin ver su causa.
Chris Cashwell
Este es un error que puede ser fácilmente replicado por cualquier cadena con 2 o más símbolos%.
zaid
Si no está buscando un propósito de formateo, es una mejor manera de lograrlo.
Shishir Gupta
En mi caso, ingresé erróneamente el parámetro de formato como 1% $ s, en lugar de% 1 $ s.
Ashokchakravarthi Nagarajan

Respuestas:

467

Android Asset Packaging Tool ( aapt) se ha vuelto muy estricta en su última versión y ahora se usa para todas las versiones de Android. El error aapt que está recibiendo se genera porque ya no permite especificadores de formato no posicionales .

Aquí hay algunas ideas sobre cómo puede incluir el símbolo% en sus cadenas de recursos.

Si no necesita ningún especificador de formato o sustituciones en su cadena, simplemente puede hacer uso del formattedatributo y establecerlo en false:

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

En este caso, la cadena no se usa como una cadena de formato para Formatterque no tenga que escapar de sus% -symbols. La cadena resultante es "% a +% a == 2% a".

Si omite el formatted="false"atributo, la cadena se usa como una cadena de formato y debe escapar de los símbolos%. Esto se hace correctamente con double-%:

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

Ahora aaptno le da errores, pero dependiendo de cómo lo use, la cadena resultante puede ser "%% a + %% a == 2 %% a" si Formatterse invoca sin ningún argumento de formato :

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"

Sin ningún código y xml es difícil decir cuál es exactamente su problema, pero espero que esto lo ayude a comprender un poco mejor los mecanismos.

Josef Pfleger
fuente
1
Seleccioné esto como la respuesta porque debería funcionar, pero aparentemente hay un error que estoy encontrando con esa cadena, así que he decidido usar %% y "XXX.replaceAll (" %% ","% ");"
zaid
44
usando formatted = false funciona muy bien. Así es como lo usé: <string name = "information_description" formatted = "false"> \ 'Sweet \' 10% a 20% incluso 35% de azúcar en peso </string>
Alguien en algún lugar
1
formatted = false también funciona bien para mí. El uso de %%, que, literalmente, se presentó como %% en mi dispositivo y un emulador ..
samwize
formateado = falso funcionó bien para mí en el pasado. ahora (ADT 22), por alguna razón no lo hace. y si uso: "str = mContext.getString (R.string.str," hello ")", tendrá esta advertencia de pelusa: "La cadena de formato 'str' no es una cadena de formato válida, por lo que no debe pasarse a String.format "
desarrollador de Android
1
Si está accediendo desde <string-array />, para el porcentaje de impresión use \ u0025. Esto funcionó para mí.
Chintan Shah
157

Para permitir que la aplicación use cadenas formateadas de recursos, debe corregir su xml. Así por ejemplo

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

debe ser reemplazado con

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

Puedes ver esto para más detalles.

Paul E.
fuente
2
Gracias, proporcionaste el eslabón perdido, literalmente.
akauppi
22
Para la sustitución de parámetros múltiples (p. Ej. Con cadenas), uso %1$s, %2$setc.
CJBS
1
¿Quién leerá una respuesta tan grande para esta pequeña cosa? Gracias, me desplazo hacia abajo para encontrarte.
Janaka R Rajapaksha
73

Puede escapar% usando %% para el analizador XML, pero se muestra dos veces en el dispositivo.

Para mostrarlo una vez, intente con el siguiente formato: \%%

Por ejemplo

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

se muestra como Fat Burning (50% to 60%)en el dispositivo

Pavblazek
fuente
66
\ %% provoca bloqueos en Nexus 4 4.2.1. No he probado a otros.
Jon Willis
Esto funciona bien y es fácil cuando ya conoce el porcentaje que desea incluir en sus cadenas, en comparación con el uso del formateador de cadenas y siempre tiene que establecer esos valores codificados mediante programación.
portfoliobuilder
Esto también se estrelló en Nexus 5.1.1. La respuesta de @ViliusK es la correcta.
Chan Jing Hong
2
uso justo %% en lugar de%
Sundeep1501
37

Utilizar

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

Llegar

80% wins como una cadena formateada

Estoy usando el String.format()método para obtener el número insertado en lugar de %d.

ViliusK
fuente
12

En su archivo strings.xml puede usar cualquier signo Unicode que desee.

Por ejemplo, el número Unicode para el signo de porcentaje es 0025:

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

Puede ver una lista completa de signos Unicode aquí

Asaf Pinhassi
fuente
1
Eso no tiene sentido. & # x0025; y% son idénticos en un archivo xml.
BeniBela
El archivo de recursos se convierte en un recurso Java y, al hacerlo, el %carácter vuelve. Me temo que esto no resuelve el problema.
Paul Lammertsma
9

para escapar del símbolo de porcentaje, solo necesita %%

por ejemplo :

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

devuelve "10%"

joven
fuente
1
Su respuesta es más o menos la misma que otras respuestas existentes
Ben Rhys-Lewis
... y mal, porque devuelve 10%no %10. FIY: cuando lo uses, String.formatsiempre debes especificar Locale. Puede ser realmente sorprendido cuando usted no pone Idioma y utiliza la configuración regional árabe para formatear números ...
mtrakal
7

No es exactamente tu problema, sino uno similar.

Si tiene más de un formato en su entrada de cadena, no debe usar "% s" varias veces.

NO HACER:

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

Hacer:

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

Puede escapar del% en xml con %%, pero necesita establecer el texto en código, no en el diseño xml.

Mee
fuente
1
Sí, se escapa con el doble% y se compila muy bien. Pero cuando se ejecuta en un emulador, o incluso en dispositivos, puede aparecer como %%.
samwize
5

Este podría ser un caso de que el IDE se vuelva demasiado estricto.

La idea es sólida, en general, debe especificar el orden de las variables de sustitución para que, si agrega recursos para otro idioma, no sea necesario cambiar su código Java. Sin embargo, hay dos problemas con esto:

En primer lugar, una cadena como:

You will need %.5G %s

para ser utilizado ya que necesitará 2.1200 mg tendrá el mismo orden en cualquier idioma ya que esa cantidad de masa siempre está representada científicamente en ese orden.

El segundo es que si coloca el orden de las variables en cualquier idioma en el que se especifiquen sus recursos predeterminados (p. Ej., Inglés), entonces solo necesita especificar las posiciones en las cadenas de recursos para los idiomas; use un orden diferente al idioma predeterminado.

La buena noticia es que esto es fácil de solucionar. Aunque no es necesario especificar las posiciones y el IDE es demasiado estricto, solo especifíquelas de todos modos. Para el ejemplo anterior use:

Necesitará% 1 $ .5G% 2 $ s

Steve Waring
fuente
4

Un método complicado: usar un pequeño signo de porcentaje como se muestra a continuación

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

Signo de porcentaje en Wikipedia

Bao Le
fuente
3

Prueba este (a la derecha):

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

Suponga que desea mostrar (50% de descuento) e ingresar 50 en tiempo de ejecución. Aquí está el código:

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

En la clase java use este código:

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

Intente usar una barra invertida frente a ella, como a continuación:

\%
lolraccoon
fuente
Esta solución lleva a estrellarse.
Prinkal Kumar