Устройство UI в Android: компоненты и кнопки

UI в Android — это дерево элементов: либо классические View/ViewGroup (императивно), либо декларативные composable-функции в Jetpack Compose; кнопки обычно следуют паттернам Material (primary, elevated, outlined, text), а для удобства и доступности touch‑target должен быть не менее 48×48 dp.

View vs Jetpack Compose — что выбрать и как работают

View (XML)

  • Подходит для существующих проектов и зрелых библиотек.
  • UI строится как иерархия ViewGroup → View; вы управляете обновлениями вручную. Jetpack Compose
  • Декларативный UI: экраны описываются функциями, фреймворк сам перерисовывает вид при смене состояния.
  • Упрощает работу со state, анимациями и тестируемостью.

Когда выбирать:

  • Новый экран в новом проекте — рассматривайте Compose.
  • Большой устоявшийся код — мигрируйте постепенно (interop возможен).

Компоненты интерфейса и их соответствия

  • Контейнеры: LinearLayout / ConstraintLayout ⇄ Column / Row / Box.
  • Текст/изображения: TextView / ImageView ⇄ Text / Image.
  • Списки: RecyclerView ⇄ LazyColumn / LazyRow.
  • Диалоги, bottom sheets и snackbar есть в библиотеках Material для обеих парадигм.

Типы кнопок и когда применять

  • Primary / Filled — главный CTA: яркая заполненная кнопка.
  • Elevated — выделяется тенью, полезна на сложных фонах.
  • Filled tonal — мягкий акцент, меньше визуального веса.
  • Outlined — вторичные действия; рамка, минимальный приоритет.
  • Text — минимальные действия, в диалогах и панелях.

Пример Compose:

ElevatedButton(onClick = onSubmit, modifier = Modifier
    .fillMaxWidth()
    .padding(16.dp)
    .minimumInteractiveComponentSize()
) {
    Text("Отправить")
}

Пример XML:

<com.google.android.material.button.MaterialButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="48dp"
    android:padding="12dp"
    android:text="Отправить" />

Если иконка визуально 24×24 dp, добавьте padding или minSize, чтобы фактическая область касания была 48×48 dp.

Доступность и практические рекомендации

  • Touch target минимум 48×48 dp; между элементами — ≈8 dp.
  • Для интерактивных иконок обязательно задавайте contentDescription.
  • Обеспечьте контраст текста и фона (проверяйте на разных темах).
  • Защищайте критичные действия от повторных нажатий (debounce или блокировка кнопки до завершения операции).
  • Размещайте главный CTA в зоне большого пальца — нижняя треть экрана.

Частая ошибка — визуально маленькие кнопки/иконки без расширенной области касания: приводит к промахам и снижает доступность.

Производительность и отладка

  • Во View уменьшайте глубину иерархии: избегайте лишних контейнеров.
  • В Compose минимизируйте ненужные recomposition: используйте remember, ключи и делите UI на мелкие composable.
  • Профилируйте layout/measure/draw, используйте инспекторы и профайлеры для поиска узких мест.

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

  • Неправильный touch target (меньше 48dp).
  • Отсутствие contentDescription у интерактивных иконок.
  • Главный CTA теряется среди равнозначных кнопок.
  • Блокировка UI при сетевых операциях без индикатора.

FAQ

  • Нужно ли переводить проект на Compose? Не обязательно; решение зависит от срока, ресурсов и объёма приложения.
  • Как гарантировать доступность кнопки? Увеличьте область касания, задайте contentDescription и проверяйте контраст.
  • Как предотвратить двойные нажатия? Отключайте кнопку после первого нажатия или используйте debounce.

Итог: стройте UI как ясное дерево элементов, выбирайте тип кнопки по приоритету действия, обеспечьте 48×48 dp touch‑target и contentDescription, тестируйте на производительность и с ассистивными технологиями.