Как хранятся тексты в Android Compose?
Что проверяют
Знаете ли вы, откуда в Compose берётся текст и как он переживает смену языка, поворот экрана и перевод на другие языки. Следом обычно спрашивают, как отдать строку из ViewModel, если там нет Context.
Как отвечать
Сам Compose строки не хранит: статичный текст лежит в ресурсах, как и в классических View, а изменяемый живёт в состоянии.
- ресурсы:
res/values/strings.xmlи переводы вvalues-en,values-deи так далее. В кодеstringResource(R.string.title), с аргументамиstringResource(R.string.greeting, name), для массивовstringArrayResource; - множественное число:
<plurals>иpluralStringResource(R.plurals.items, count, count). Для русского это обязательно, у него формы one, few и many, и проверкаcount == 1их не покрывает; - стилизованный текст: тип
AnnotatedString, собирается черезbuildAnnotatedStringсоSpanStyle. В свежих версиях Compose естьAnnotatedString.fromHtml, который понимает разметку из ресурсов, включая ссылки; - изменяемый текст:
mutableStateOfвнутриrememberилиrememberSaveable, если значение должно пережить поворот и смерть процесса. Для полей ввода естьTextFieldState; - текст из
ViewModel: не строка, а описание строки. Обычно этоsealed class UiTextс id ресурса и аргументами, а в строку он превращается уже в composable.
stringResource читает конфигурацию через LocalContext, поэтому при смене языка экран перерисуется с новыми строками. Язык приложения отдельно от системного задаётся через AppCompatDelegate.setApplicationLocales, на Android 13 и выше это системная настройка языка для каждого приложения. В Compose Multiplatform ресурсы свои: каталог composeResources и сгенерированный класс Res.
Где спотыкаются
Зовут context.getString() во ViewModel и хранят готовую строку. После смены языка на экране остаётся старый текст, а во ViewModel утекает ссылка на контекст.
Собирают фразу конкатенацией: "Привет, " + name. Переводчик не может поменять порядок слов, нужны плейсхолдеры %1$s.
Хардкодят строки прямо в Text("..."). Lint об этом предупреждает, а локализация потом превращается в поиск по всему проекту.