Если в моем 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>
Я показываю результат пользователю, используя:
textView.setText(getQuantityString(R.plurals.item_shop, quantity, quantity));
Он хорошо работает с 1 и выше, но если количество равно 0, я вижу «0 элементов». Поддерживается ли «нулевое» значение только на арабском языке, как, кажется, указано в документации? Или я что-то упускаю?
Ответы:
Метод интернационализации ресурсов Android весьма ограничен. Я добился большего успеха при использовании стандарта
java.text.MessageFormat
.По сути, все, что вам нужно сделать, это использовать стандартный строковый ресурс следующим образом:
<resources> <string name="item_shop">{0,choice,0#No items|1#One item|1<{0} items}</string> </resources>
Затем из кода все, что вам нужно сделать, это следующее:
String fmt = getResources().getText(R.string.item_shop).toString(); textView.setText(MessageFormat.format(fmt, amount));
Вы можете узнать больше о строках формата в документации javadoc для MessageFormat.
источник
Из http://developer.android.com/guide/topics/resources/string-resource.html#Plurals :
Обратите внимание, что выбор сделан исходя из грамматической необходимости. Строка для нуля на английском языке будет проигнорирована, даже если количество равно 0, потому что 0 грамматически не отличается от 2 или любого другого числа, кроме 1 («ноль книг», «одна книга», «две книги» и т. Д. на). Не заблуждайтесь и тем фактом, что, скажем, два звука, как будто они могут применяться только к величине 2: язык может требовать, чтобы 2, 12, 102 (и так далее) обрабатывались как друг друга, но по-разному. количества. Положитесь на своего переводчика, чтобы знать, на каких различиях на самом деле настаивает их язык.
В заключение, «ноль» используется только для определенных языков (то же самое для «два», «несколько» и т. Д.), Потому что другие языки не имеют специального спряжения, и поэтому поле «ноль» считается ненужным.
источник
Вот обходной путь, который я использую для решения этой проблемы без переключения на MessageFormat.
Сначала я извлекаю «нулевую» строку в ее собственный строковый ресурс.
<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>
Тогда у меня есть несколько удобных методов в моем собственном ResourcesUtil
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); } }
Теперь, когда я хочу использовать конкретную строку для нулевого количества, я вызываю:
String pluralString = ResourcesUtil.getQuantityStringZero( getContext().getResources(), R.plural.x_items, R.string.x_items_zero, quantity );
Я бы хотел, чтобы было что-то получше, но это, по крайней мере, выполняет свою работу, сохраняя разборчивость XML-строкового ресурса.
источник
Android использует систему множественного числа CLDR, и это просто не так, как это работает (поэтому не ожидайте, что это изменится).
Система описана здесь:
http://cldr.unicode.org/index/cldr-spec/plural-rules
Короче говоря, важно понимать, что «один» не означает число 1. Вместо этого эти ключевые слова являются категориями, а конкретные числа n, которые принадлежат каждой категории, определяются правилами в базе данных CLDR:
http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
Хотя, похоже, не существует языка, который использует «ноль» для чего-либо, кроме 0, есть языки, которые присваивают 0 «единице». Конечно, существует множество случаев, когда «два» содержит другие числа, чем просто 2.
Если Android позволяет вам делать то, что вы намеревались, ваши приложения не могут быть должным образом переведены на любое количество языков с более сложными правилами множественного числа.
источник
Я написал расширение Kotlin для обработки всех возможных сценариев.
У меня есть
zeroResId
как необязательный, поэтому иногда мы хотим обработать ноль, отображая «Нет элементов», а не «0 элементов».В английском языке ноль грамматически трактуется как множественное число.
https://developer.android.com/guide/topics/resources/string-resource.html#Plurals
fun Context.getQuantityStringZero( quantity: Int, pluralResId: Int, zeroResId: Int? = null ): String { return if (zeroResId != null && quantity == 0) { resources.getString(zeroResId) } else { resources.getQuantityString(pluralResId, quantity, quantity) } }
источник
Если вы используете привязку данных, вы можете обойти это примерно так:
<TextView ... android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>
источник