Как организовать и подключать строки, drawables и стили в res

Короткий ответ: храните строки в res/values/strings.xml, изображения в res/drawable-*/ или mipmap-*/, стили в res/values/styles.xml и подключайте их через @string/..., @drawable/..., @style/... в XML или через R.string..., ContextCompat.getDrawable(...) и R.style... в коде. Используйте qualifiers (density, language, night) и векторные ресурсы для универсальности.

Куда и как хранить основные ресурсы

  • Строки: res/values/strings.xml. Для множественного числа — plurals (<plurals name="items">), для разных языков — папки values-ru/, values-en/.
  • Цвета и размеры: res/values/colors.xml, res/values/dimens.xml. Используйте @color/primary и @dimen/margin_small.
  • Стили и темы: res/values/styles.xml. Разделяйте стили компонентов и темы приложения; наследуйте стили (<style name="MyButton" parent="Widget.Material.Button">).
  • Изображения: res/drawable-mdpi/, drawable-hdpi/, drawable-xhdpi/ или единообразно drawable/ + векторные (.xml). Иконки запуска — mipmap-*/.
  • Прочие: res/raw/ для медиа/файлов, res/xml/ для конфигураций (например, preferences.xml), assets/ для свободных файлов.

Используйте векторные drawables (VectorDrawable) для иконок и простых иллюстраций — они уменьшают вес и автоматически масштабируются для разных плотностей.

Как подключать ресурсы в XML и коде

  • XML (Layout, Menu, Drawable):
    • Текст: android:text="@string/title"
    • Изображение: android:src="@drawable/ic_logo" или app:srcCompat="@drawable/ic_logo" для совместимости
    • Стиль: style="@style/MyButton" или тема: android:theme="@style/MyTheme"
  • В Kotlin/Java:
    • Строка: val s = context.getString(R.string.title)
    • Drawable: val d = ContextCompat.getDrawable(context, R.drawable.ic_logo)
    • Размер: val px = resources.getDimensionPixelSize(R.dimen.padding)
    • Применение стиля программно: использовать ContextThemeWrapper или obtainStyledAttributes.
  • Темы и атрибуты: в стилях ссылайтесь на атрибуты ?attr/colorPrimary для обеспечения смены темы.

Не используйте getResources().getDrawable(int) без указания темы на Android новых версий — это может вернуть не того цвета из-за tint/attr. Применяйте ContextCompat.getDrawable.

Лучшие практики и организация проекта

  • Именование: snake_case с префиксами (btn_submit, ic_user, bg_header) — улучшает поиск.
  • Локализация: поместите все текстовые ресурсы в strings.xml, используйте plurals и тестируйте переключение локалей.
  • Разделение тем: храните общие атрибуты в themes.xml, отдельные стили для компонентов в styles.xml.
  • Оптимизация изображений: конвертируйте в WebP или используйте вектора; избегайте дублирования одних и тех же PNG в разных папках.
  • Используйте resource qualifiers: drawable-night/ для тёмной темы, values-sw600dp/ для планшетов и т.д.
  • Модули и feature-модуляция: при больших проектах выносите ресурсы фич в соответствующие модули, но следите за дублированием имен.
  • Сборка: включайте resource shrinking (shrinkResources true) и обфускацию, чтобы удалить неиспользуемые ресурсы.

Частые ошибки

  • Хардкодить строки в layout вместо @string/....
  • Класть иконку лаунчера в drawable вместо mipmap (результат: иконки масштабируются некорректно на некоторых лаунчерах).
  • Дублирование ресурсов с разными именами в разных модулях — приводит к конфликтам при сборке.
  • Игнорирование плотностей экранов — большие PNG без версии для mdpi/hdpi.
  • Неиспользование plurals для счетчика предметов — неверное склонение в языках.

FAQ

  • Q: Когда использовать mipmap вместо drawable?
    A: Для иконок лаунчера — mipmap предпочтительнее, т.к. система может использовать разные плотности вне зависимости от ресурсов приложения.
  • Q: Можно ли хранить строки прямо в коде?
    A: Технически да, но это мешает локализации и тестированию — всегда используйте strings.xml.
  • Q: Как поддержать тёмную тему для ресурсов?
    A: Создайте values-night/ для цветов и стилей или drawable-night/ для изображений, и используйте атрибуты темы.
  • Q: Как оптимизировать размер APK по ресурсам?
    A: Используйте WebP/Vector, включите resource shrinking в Gradle и удаляйте неиспользуемые ресурсы.

Если нужно, подготовлю чеклист по наименованию ресурсов или примеры конфигураций styles.xml и themes.xml под Material 3.