Множественное использование Android для "нулевого"

Если в моем файле strings.xml имеется следующий множественный ressource:

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

Ответ 1

Метод интернационализации ресурса 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

Ответ 2

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

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

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

Ответ 3

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 "одному". Есть, конечно, много случаев, когда "два" содержат другие числа, кроме двух.

Если Android, где вы можете делать то, что вы намеревались, ваши приложения не могут быть надлежащим образом переведены на любое количество языков с более сложными множественными правилами.

Ответ 4

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

Затем у меня есть некоторые удобные методы в моих собственных ресурсахUtil

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 разборчивым.

Ответ 5

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

<TextView ... 
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>