Android множественное число лечения "ноль" - PullRequest
74 голосов
/ 13 апреля 2011

Если у меня есть следующий множественный ресурс в моем 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 товаров».Поддерживается ли «нулевое» значение только на арабском языке, как видно из документации?Или я что-то упустил?

Ответы [ 5 ]

78 голосов
/ 15 апреля 2011

Ресурсный метод Android для интернационализации довольно ограничен. У меня был гораздо лучший успех при использовании стандарта java.text.MessageFormat.

По сути, все, что вам нужно сделать, это использовать стандартный строковый ресурс, подобный этому:

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

Затем из кода все, что вам нужно сделать, это следующее:

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

Подробнее о строках формата вы можете прочитать в javadocs для MessageFormat

40 голосов
/ 04 апреля 2012

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

Обратите внимание, что выбор сделан на основе грамматической необходимости. Строка для нуля на английском языке будет игнорироваться, даже если количество равно 0, потому что 0 не отличается грамматически от 2 или любого другого числа, кроме 1 («ноль книг», «одна книга», «две книги» и т. Д.). на). Не вводите в заблуждение и тот факт, что, скажем, два звука могут относиться только к количеству 2: язык может требовать, чтобы 2, 12, 102 (и т. Д.) Рассматривались как один другой, но по-другому величины. Доверьтесь своему переводчику, чтобы узнать, на каких отличиях их язык на самом деле настаивает.

В заключение, «ноль» используется только для определенных языков (то же самое относится и к «двум», «немногим» и т. Д.), Потому что другие языки не имеют специального сопряжения и, следовательно, поле «ноль» считается ненужным

13 голосов
/ 03 марта 2012

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 где разрешить вам делать то, что вы хотели, ваши приложения не могут быть должным образом переведены на любое количество языков с более сложными правилами множественного числа.

9 голосов
/ 21 марта 2016

Вот обходной путь, который я использую для решения этой проблемы без переключения на 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 строкового ресурса.

0 голосов
/ 24 августа 2016

Если вы используете привязку данных, вы можете обойти это примерно так:

<TextView ... 
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...