Как оформить и подключить иконки и кнопки в Android — кратко и практично

Короткий ответ: используйте VectorDrawable или адаптивные иконки для масштабируемости, MaterialButton (MD3) для кнопок, храните ресурсы в res/drawable и res/mipmap, и тестируйте на разных DPI и темах.

Основы иконок: форматы, размеры и где хранить

  1. Предпочтение — векторным иконкам (VectorDrawable). Они масштабируются без артефактов и уменьшают размер APK при правильной оптимизации.
  2. Когда нужен PNG: для сложной растровой графики или при поддержке старых API. Подготовьте версии для mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi.
  3. Адаптивные иконки (launcher) — два слоя: foreground и background в res/mipmap-anydpi-v26/. Это обязательно для Android 8+.
  4. Пример VectorDrawable (res/drawable/ic_home.xml):
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp" android:height="24dp"
    android:viewportWidth="24" android:viewportHeight="24">
  <path android:fillColor="#000000"
        android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>
  1. Размещение: векторные и селекторы — res/drawable/, лаунчер-иконки — res/mipmap/. Имена ресурсов короткие и понятные: ic_home.xml, ic_search.xml.

При создании векторных иконок избегайте сложных фильтров и масок — они увеличивают время рендера и могут не поддерживаться на старых версиях.

Оформление кнопок и подключение drawable-ресурсов

  1. Используйте компоненты Material (MD3) — MaterialButton обеспечивает стили, иконки и состояние по умолчанию.
  2. XML-пример кнопки с иконкой:
<com.google.android.material.button.MaterialButton
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Домой"
    android:icon="@drawable/ic_home"
    app:iconGravity="start"
    app:cornerRadius="12dp"
    style="@style/Widget.Material3.Button.Primary"/>
  1. В Kotlin:
val btn = findViewById<MaterialButton>(R.id.myButton)
btn.setOnClickListener { /* действие */ }
btn.icon = ContextCompat.getDrawable(this, R.drawable.ic_home)
  1. Селектор для фоновых состояний (res/drawable/button_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <shape android:shape="rectangle">
      <solid android:color="#E0E0E0"/>
      <corners android:radius="8dp"/>
    </shape>
  </item>
  <item>
    <shape android:shape="rectangle">
      <solid android:color="#FFFFFF"/>
      <stroke android:width="1dp" android:color="#CCCCCC"/>
      <corners android:radius="8dp"/>
    </shape>
  </item>
</selector>
  1. Темы: определяйте colorPrimary, colorOnPrimary в res/values/colors.xml и отдельные значения для res/values-night/colors.xml. Для состояний используйте color state lists.

Не задавайте фиксированные размеры иконкам в dp везде — используйте app:iconSize или задавайте в стиле, чтобы иконки адаптировались под разные плотности и размеры кнопок.

Адаптация UI, Compose и тестирование на разных экранах

  1. Макеты: ConstraintLayout для адаптивности; используйте layout_constraintDimensionRatio и chain для гибкого расположения.
  2. Размер иконок в кнопках: app:iconSize="24dp" для консистентности — но делайте размеры в ресурсах (dimens.xml) для масштабирования.
  3. Jetpack Compose — пример:
Button(onClick = { /* */ }, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary)) {
  Icon(Icons.Default.Home, contentDescription = "Домой")
  Spacer(Modifier.size(ButtonDefaults.IconSpacing))
  Text("Домой")
}
  1. Доступность: всегда указывайте contentDescription (или null для декоративных иконок), увеличивайте touch target до минимум 48dp.
  2. Производительность: отдавайте предпочтение VectorDrawable, используйте AnimatedVectorDrawable для простых анимаций; для сложной анимации — Lottie.
  3. Тестируйте: Layout Validation и Layout Inspector в Android Studio, эмуляторы с разными DPI и реальные устройства (360×640…1440×3200).

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

  • Использование растровых PNG без множества density-версий → размытые иконки.
  • Фиксированные размеры для кнопок и иконок, которые ломают адаптивность.
  • Отсутствие contentDescription → плохая доступность.
  • Использование сложных векторных эффектов, которые тормозят рендер.

FAQ

  • Нужно ли всегда использовать VectorDrawable? Да, если иконка простая (контуры, заливки). Для фотографий — PNG/WebP.
  • Где хранить иконки для лаунчера? В res/mipmap-anydpi-v26/ как адаптивные и в res/mipmap-*/ для PNG-версий.
  • Как добавить разные состояния кнопки? Через selector в drawable или color state list для текстов/иконок.

Соблюдая эти шаги, вы получите компактный, масштабируемый и доступный UI: начните с Vector Asset, задайте темы MD3 и протестируйте на нескольких устройствах.