pie - android versiones
Tratamiento de plurals de Android de "cero" (5)
Android está usando el sistema de plurales CLDR, y así no es como funciona (así que no esperes que esto cambie).
El sistema se describe aquí:
http://cldr.unicode.org/index/cldr-spec/plural-rules
En resumen, es importante entender que "uno" no significa el número 1. En cambio, estas palabras clave son categorías, y los números específicos n que pertenecen a cada categoría están definidos por las reglas en la base de datos CLDR:
http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
Si bien parece que no hay ningún idioma que utiliza "cero" para cualquier cosa que no sea 0, hay idiomas que asignan 0 a "uno". Ciertamente, hay muchos casos en que "dos" contiene otros números además de solo 2.
Si Android permitiera hacer lo que usted deseaba, sus aplicaciones no podrían traducirse correctamente a cualquier número de idiomas con reglas de plural más complejas.
Si tiene el siguiente recurso plural en mi strings.xml:
<plurals name="item_shop">
<item quantity="zero">No item</item>
<item quantity="one">One item</item>
<item quantity="other">%d items</item>
</plurals>
Estoy mostrando el resultado al usuario que usa:
textView.setText(getQuantityString(R.plurals.item_shop, quantity, quantity));
Está funcionando bien con 1 y más, pero si la cantidad es 0, entonces veo "0 elementos". ¿El valor "cero" solo se admite en árabe, como parece indicar la documentación? ¿O me estoy perdiendo algo?
Aquí hay una solución que estoy usando para manejar este problema sin cambiar a MessageFormat.
Primero, extraigo la cadena "cero" en su propio recurso de cadena.
<string name="x_items_zero">No items.</string>
<plurals name="x_items">
<!-- NOTE: This "zero" value is never accessed but is kept here to show the intended usage of the "zero" string -->
<item quantity="zero">@string/x_items_zero</item>
<item quantity="one">One item.</item>
<item quantity="other">%d items.</item>
</plurals>
Luego tengo algunos métodos de conveniencia en mis propios recursosUtilizar
public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity) {
if (quantity == 0) {
return resources.getString(zeroResId);
} else {
return resources.getQuantityString(resId, quantity, quantity);
}
}
public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity, Object... formatArgs) {
if (quantity == 0) {
return resources.getString(zeroResId);
} else {
return resources.getQuantityString(resId, quantity, formatArgs);
}
}
Ahora cuando quiera usar una cadena específica para la cantidad cero, llamo:
String pluralString = ResourcesUtil.getQuantityStringZero(
getContext().getResources(),
R.plural.x_items,
R.string.x_items_zero,
quantity
);
Desearía que hubiera algo mejor, pero al menos hace el trabajo mientras se mantiene legible el XML del recurso de cadena.
Desde http://developer.android.com/guide/topics/resources/string-resource.html#Plurals :
Tenga en cuenta que la selección se realiza en función de la necesidad gramatical. Una cadena para cero en inglés será ignorada incluso si la cantidad es 0, porque 0 no es gramaticalmente diferente de 2, o cualquier otro número excepto 1 ("cero libros", "un libro", "dos libros", y así en). No se deje engañar tampoco por el hecho de que, digamos, dos sonidos como que solo pueden aplicarse a la cantidad 2: un lenguaje puede requerir que 2, 12, 102 (y así sucesivamente) se traten unos a otros pero de manera diferente a otros cantidades. Confíe en su traductor para saber qué distinciones realmente insiste su lenguaje.
En conclusión, ''cero'' solo se usa para ciertos idiomas (lo mismo vale para ''dos'' ''pocos'', etc.) porque los otros idiomas no tienen una conjugación especial y, por lo tanto, el campo ''cero'' se considera innecesario.
El método de internacionalización de recursos de Android es bastante limitado. He tenido mucho mejor éxito utilizando el estándar java.text.MessageFormat
.
Básicamente, todo lo que tienes que hacer es usar el recurso de cadena estándar como este:
<resources>
<string name="item_shop">{0,choice,0#No items|1#One item|1<{0} items}</string>
</resources>
Entonces, del código todo lo que tienes que hacer es lo siguiente:
String fmt = getResources().getText(R.string.item_shop).toString();
textView.setText(MessageFormat.format(fmt, amount));
Puede leer más sobre las cadenas de formato en los javadocs para MessageFormat
Si está utilizando el enlace de datos puede solucionarlo con algo como:
<TextView ...
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>