Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Ресурсы plurals. Множественное число

Когда нам нужно вывести какое-то количество, то возникает проблема с окончаниями. Самый простой способ решения проблемы заключается в использовании двоеточия:


Всего котиков: 5

Но хочется более элегантного решения. Для подобных случаев есть специальный вид ресурсов plurals. Следует отметить, что в старых версиях русский язык использовать было проблематично из-за ошибок. Но в версии Android 3.0 (API 11) всё починили.

В обычном файле строковых ресурсов strings.xml создаём ресурс pluras, в котором задаётся набор правил склонения нужного выражения. В коде нужно указать нужный вариант для заданных чисел.

Дочерний элемент item имеет обязательный атрибут quantity, который указывает на диапазон чисел.

  • zero — строка для нуля, отсутствия чего-либо; в некоторых языках — ещё и для чисел, оканчивающихся нулём;
  • one — строка для чисел, заканчивающихся на единицу; в некоторых языках — только для единицы;
  • two — для чисел, заканчивающихся на двойку, или только для двойки;
  • few — зависит от языковых правил; например, для русского языка это относится к числам, оканчивающимся на 2, 3 и 4 (несмотря на наличие правила «two»);
  • many — также зависит от языковых правил; в русском языке — от пятёрки и выше;
  • other — остальные варианты

Чтобы лучше уяснить механизм работы с множественными числами, создадим ресурс и проверим на практике.


<!-- Этот код мы используем для отладки: когда какой item выбирается системой -->
<plurals name="plurals_1">
    <item quantity="zero">%1$d = zero</item>
    <item quantity="one">%1$d = one</item>
    <item quantity="two">%1$d = two</item>
    <item quantity="few">%1$d = few</item>
    <item quantity="many">%1$d = many</item>
    <item quantity="other">%1$d = other</item>
</plurals>

<!-- А этот код мы используем для проверки того, как выглядит реальное склонение -->
<plurals name="plurals_2">
    <item quantity="zero">нет котов</item>
    <item quantity="one">%1$d кот</item>
    <item quantity="two">%1$d кота</item>
    <item quantity="few">%1$d кота</item>
    <item quantity="many">%1$d котов</item>
    <item quantity="other">%1$d котов</item>
</plurals>

В коде вызываем метод Resources.getQuantityString(), где id — идентификатор нашего ресурса plurals (R.plurals.xxx), quantity — число, для которого нужно найти словоформу и дополнительные параметры formatArgs для подстановки в строку по шаблону.

Протестируем вывод чисел от нуля до тридцати трёх:


// Выведем данные в формате: 8 = many : 8 котов
for (int i = 0; i <= 33; i++) {
    String systemPlural = this.getResources().getQuantityString(R.plurals.plurals_1, i, i);
    String catPlural = this.getResources().getQuantityString(R.plurals.plurals_2, i, i);
    Log.i("Plurals", systemPlural + " : " + catPlural);
}

В цикле получаем из ресурсов строку, согласующуюся (по мнению системы) со счётчиком цикла, на место шаблона %1$d подставляем значение этого счётчика.

Посмотрим, как система выводит количество 33 котов.


I/Plurals: 0 = many : 0 котов
I/Plurals: 1 = one : 1 кот
I/Plurals: 2 = few : 2 кота
I/Plurals: 3 = few : 3 кота
I/Plurals: 4 = few : 4 кота
I/Plurals: 5 = many : 5 котов
I/Plurals: 6 = many : 6 котов
I/Plurals: 7 = many : 7 котов
I/Plurals: 8 = many : 8 котов
I/Plurals: 9 = many : 9 котов
I/Plurals: 10 = many : 10 котов
I/Plurals: 11 = many : 11 котов
I/Plurals: 12 = many : 12 котов
I/Plurals: 13 = many : 13 котов
I/Plurals: 14 = many : 14 котов
I/Plurals: 15 = many : 15 котов
I/Plurals: 16 = many : 16 котов
I/Plurals: 17 = many : 17 котов
I/Plurals: 18 = many : 18 котов
I/Plurals: 19 = many : 19 котов
I/Plurals: 20 = many : 20 котов
I/Plurals: 21 = one : 21 кот
I/Plurals: 22 = few : 22 кота
I/Plurals: 23 = few : 23 кота
I/Plurals: 24 = few : 24 кота
I/Plurals: 25 = many : 25 котов
I/Plurals: 26 = many : 26 котов
I/Plurals: 27 = many : 27 котов
I/Plurals: 28 = many : 28 котов
I/Plurals: 29 = many : 29 котов
I/Plurals: 30 = many : 30 котов
I/Plurals: 31 = one : 31 кот
I/Plurals: 32 = few : 32 кота
I/Plurals: 33 = few : 33 кота

Система справилась. Мы получили правильные окончания: 1 кот, 2 кота, 5 котов, 31 кот и т.д.

Русский язык требует указать строки для one, few, many и other (на всякий случай). По стандарту не используется zero, и не используется two — но, ничего страшного в указании этих строк нет. На всякий случай можно их всё-таки указывать — кто знает, а вдруг что-то поменяется в будущем.

Реклама