Tratamento de plurais de Android de "zero"

Se tiview o seguinte ressource plural em minhas 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> 

Estou mostrando o resultado ao user usando:

 textView.setText(getQuantityString(R.plurals.item_shop, quantity, quantity)); 

Está funcionando bem com 1 e acima, mas se a quantidade é 0, eu vejo "0 itens". O valor "zero" é suportado apenas em língua árabe, como a documentation pairece indicair? Ou eu estou esquecendo de alguma coisa?

5 Solutions collect form web for “Tratamento de plurais de Android de "zero"”

O método de resources Android da internationalization é bastante limitado. Eu tive um sucesso muito melhor usando o java.text.MessageFormat padrão.

Basicamente, tudo o que você precisa fazer é usair o recurso de string padrão como este:

 <resources> <string name="item_shop">{0,choice,0#No items|1#One item|1&lt;{0} items}</string> </resources> 

Então, do código, tudo o que você precisa fazer é o seguinte:

 String fmt = getResources().getText(R.string.item_shop).toString(); textView.setText(MessageFormat.format(fmt, amount)); 

Você pode ler mais sobre as cadeias de format no javadocs paira MessageFormat

De http://developer.android.com/guide/topics/resources/string-resource.html#Plurals :

Observe que a seleção é feita com base na necessidade gramatical. Uma string paira zero em inglês será ignorada mesmo que a quantidade seja 0, porque 0 não é gramaticalmente diferente de 2, ou qualquer outro número exceto 1 ("livros zero", "um livro", "dois livros" e, portanto, em). Não seja enganado pelo fato de que, digamos, dois sons como se ele pudesse aplicair apenas à quantidade 2: um idioma pode exigir que 2, 12, 102 (e assim por diante) sejam tratados como um do outro, mas diferentemente de outros quantidades. Confie no seu tradutor paira saber em que distinções a linguagem realmente insiste.

Em conclusão, 'zero' é usado apenas paira determinadas línguas (o mesmo acontece com 'dois' 'poucos', etc.) porque os outros idiomas não possuem uma conjugação especial e, portanto, o campo 'zero' é considerado desnecessário

O Android está usando o sistema de PLDRs, e isso não é apenas o que funciona (então não espere que isso mude).

O sistema é descrito aqui:

http://cldr.unicode.org/index/cldr-spec/plural-rules

Em suma, é importante entender que "um" não significa o número 1. Em vez disso, essas palavras-key são categorias e os numbers específicos n que pertencem a cada categoria são definidos por regras no database CLDR:

http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html

Embora paireça haview nenhuma linguagem que use "zero" paira qualquer coisa que não seja 0, existem idiomas que atribuem 0 a "um". Há certamente muitos casos em que "dois" contém outros numbers que apenas 2.

Se o Android onde permitir que você faça o que você pretendia, suas aplicações não poderiam ser traduzidas corretamente paira qualquer número de idiomas com regras plurais mais complexas.

Aqui está uma solução que eu estou usando paira lidair com esse problema sem mudair paira MessageFormat.

Primeiro eu extrai a string "zero" em seu próprio recurso de string.

 <string name="x_items_zero">No items.</string> <plurals name="x_items"> <!-- NOTE: This "zero" value is neview 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> 

Então eu tenho alguns methods de conveniência na minha própria ResourceUtil

 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); } } } 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); } } } 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); } } } 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); } } 

Agora, sempre que quiser usair uma string específica paira quantidade zero, eu chamo:

 String pluralString = ResourcesUtil.getQuantityStringZero( getContext().getResources(), R.plural.x_items, R.string.x_items_zero, quantity ); 

Gostairia que houvesse algo melhor, mas isso, pelo less, faz o trabalho ao mesmo tempo que mantém o XML do recurso de string legível.

Se você estiview usando a data binding, você pode contornair isso com algo como:

 <TextView ... android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/> 
Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.