Как обрабатывать числовые значения в строках Android для разных языков?
Androidинтернационализацияобработка строкразработка под Androidчисловые значения
Что проверяют
Знаете ли вы, что число в переводимой строке это три задачи: формат самого числа по локали, форма слова рядом с ним и позиция числа во фразе. Следом обычно спрашивают про плюралы в русском и парсинг ввода с запятой.
Как отвечать
- плейсхолдеры: в
strings.xmlпишутНайдено %1$d вакансий, нумерованные аргументы позволяют переводчику переставить их местами. ВызовgetString(R.string.found, count); - формат числа:
%dучитывает локаль, но разделители групп даёт только%,d. Надёжнее отформатировать заранее черезNumberFormat.getInstance(locale)илиandroid.icu.number.NumberFormatter(API 30+) и подставить через%1$s. Для денегNumberFormat.getCurrencyInstance, для процентовgetPercentInstance; - плюралы: ресурс
<plurals>с формамиone,few,many,otherиresources.getQuantityString(R.plurals.found, count, count). Число передают дважды: для выбора формы и для подстановки. В русском нужны все четыре формы,otherидёт для дробных; - Compose:
stringResourceиpluralStringResource; - локаль: берите её из
Configurationтекущего контекста. С Android 13 у приложения бывает свой язык, отличный от системного, через per-app language иAppCompatDelegate.setApplicationLocales; - ввод:
NumberFormat.parseс локалью пользователя иinputType="numberDecimal". В русской локали разделитель запятая, аtoDouble()её не поймёт; - проверка: псевдолокали
en-XA(длинные строки) иar-XB(RTL) в настройках разработчика.
Где спотыкаются
Склеивают строку из кусков: count.toString() + " " + getString(R.string.found). Переводчик не может поменять порядок слов, а в части языков число стоит после существительного.
Выбирают форму вручную через if (count == 1) или используют <plurals> для «ноль или не ноль». В русском 21 это one, а 11 это many, ручная логика ломается уже на втором десятке.
Парсят ввод через toDouble() без учёта локали и получают NumberFormatException на «3,5».