TopAppBar: что это, настройка и использование в Jetpack Compose

Автор: IT Sectr Опубликовано: 2026-06-29 Время чтения: 8 мин

TopAppBar — это компонент Material Design, который отображает верхнюю панель приложения с заголовком, навигационной кнопкой и дополнительными действиями. В Jetpack Compose TopAppBar реализуется через composable-функцию TopAppBar из библиотеки Material. По данным официальной документации Android Developers (2025), TopAppBar поддерживает Material2 и Material3, включая адаптивную высоту, цвета и анимацию. Панель автоматически подстраивается под системный статус-бар и корректно работает с Insets. TopAppBar используется как основная точка входа для навигации и контекстных действий в Android-приложениях.

Главное

  • TopAppBar — composable-компонент Material Design для верхней панели приложения в Jetpack Compose
  • Параметры включают title, navigationIcon, actions и модификаторы для гибкой настройки
  • Material3 предоставляет TopAppBar с поддержкой dynamic color и адаптивных отступов
  • Навигационная кнопка используется для открытия Drawer или возврата на предыдущий экран
  • ScrollBehavior позволяет скрывать TopAppBar при прокрутке контента для экономии пространства

Что такое TopAppBar в Jetpack Compose?

TopAppBar — это composable-функция из библиотеки Material Design для Jetpack Compose, реализующая верхнюю панель приложения (App Bar). Компонент отображает заголовок текущего экрана, навигационную кнопку слева и дополнительные действия справа.

В отличие от классической View-системы, Compose-версия TopAppBar полностью декларативна: панель перерисовывается при изменении состояния, а не управляется через findViewById. TopAppBar использует концепцию slot API, где title, navigationIcon и actions передаются как composable-лямбды. Это позволяет кастомизировать любой элемент панели без наследования.

По данным Google Material Design (2025), TopAppBar в Compose бывает трёх типов: CenterAlignedTopAppBar (центрированный заголовок), SmallTopAppBar (стандартный) и MediumTopAppBar (расширенный). Каждый тип определяет высоту панели, размер шрифта заголовка и поведение при скролле. Центрированный вариант чаще используется на главных экранах, а MediumTopAppBar — для страниц с контентом, где заголовок плавно уменьшается при прокрутке.

Для корректной работы TopAppBar необходимо учитывать системные отступы: Insets из WindowInsetsCompat. По рекомендации Android Developers (2025), вызов Modifier.statusBarsPadding() или windowInsetsPadding(WindоwInsets.systemBars) предотвращает наложение панели на статус-бар.

Параметры TopAppBar: настройка заголовка и модификаторов

Компонент TopAppBar принимает ряд обязательных и опциональных параметров. Основной — title, куда передаётся composable-блок с текстом заголовка. Поскольку title — это @Composable лямбда, можно вставить не только текст, но и иконку с текстом, верстать строку поиска или отображать прогресс.

kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppTopBar() {
    TopAppBar(
        title = { Text("Main") },
        navigationIcon = {
            IconButton(onClick = { /* open drawer */ }) {
                Icon(
                    Icons.Filled.Menu,
                    contentDescription = "Menu"
                )
            }
        },
        actions = {
            IconButton(onClick = { /* search */ }) {
                Icon(Icons.Filled.Search, contentDescription = "Search")
            }
        }
    )
}

Параметр Modifier позволяет задать отступы, размер и выравнивание для всей панели. Через Modifier.heightIn можно ограничить минимальную и максимальную высоту. Параметр colors принимает объект TopAppBarColors для переопределения цветов фона, заголовка и иконок.

По умолчанию TopAppBar использует цветовую схему из текущей темы MaterialTheme. Если нужна кастомная палитра, используйте TopAppBarDefaults.smallTopAppBarColors(). В Material3 фоновый цвет автоматически подстраивается под surfaceColor в светлой и тёмной темах, что исключает необходимость ручной настройки.

ПараметрТипОписание
title@Composable () -> UnitБлок заголовка панели
navigationIcon@Composable () -> UnitИконка навигации (гамбургер/стрелка)
actions@Composable RowScope.() -> UnitБлок экшенов справа
scrollBehaviorTopAppBarScrollBehavior?Поведение при скролле
colorsTopAppBarColorsЦветовая схема панели

NavigationIcon — это composable-блок в левой части TopAppBar, через который реализуется навигация. Типичные сценарии: открытие Navigation Drawer (иконка Menu), возврат на предыдущий экран (иконка ArrowBack) или закрытие текущего экрана (иконка Close).

Выбор иконки зависит от положения экрана в стеке навигации. Если экран корневой — отображается иконка Menu для открытия Drawer. Если экран вложенный — иконка ArrowBack для возврата. В Compose эта логика реализуется через NavController: текущий back stack entry определяет, какую иконку показывать.

По рекомендации Material Design (2025), ширина навигационной области составляет 48 dp — стандартный таргет для touch-взаимодействия. Иконка должна быть кликабельной с визуальной обратной связью (ripple). В Compose это обеспечивается обёрткой в IconButton с onClick-колбэком, который запускает навигацию.

При использовании Scaffold навигационная кнопка может дублировать DrawerState, который передаётся в Scaffold, а не в TopAppBar напрямую. В этом случае navigationIcon ссылается на состояние Drawer через rememberDrawerState.

Добавление экшенов и выпадающего меню

Параметр actions в TopAppBar принимает composable-блок с контекстом RowScope, что позволяет размещать несколько иконок или кнопок справа от заголовка. Каждый action должен быть кликабельным иконографическим элементом: поиск, уведомления, настройки, избранное.

Для переполненных экшенов используется выпадающее меню через DropdownMenu. Если количество действий превышает три, лишние помещаются в OverflowMenu с иконкой MoreVert. При нажатии открывается список скрытых экшенов. DropdownMenu автоматически позиционируется относительно иконки.

kotlin
@Composable
fun TopBarWithOverflow() {
    var menuExpanded by remember { mutableStateOf(false) }
    TopAppBar(
        title = { Text("Profile") },
        actions = {
            IconButton(onClick = { /* share */ }) {
                Icon(Icons.Filled.Share, contentDescription = "Share")
            }
            Box {
                IconButton(onClick = { menuExpanded = true }) {
                    Icon(Icons.Filled.MoreVert, contentDescription = "More")
                }
                DropdownMenu(
                    expanded = menuExpanded,
                    onDismissRequest = { menuExpanded = false }
                ) {
                    DropdownMenuItem(text = { Text("Settings") }, onClick = { /* navigate */ })
                    DropdownMenuItem(text = { Text("About") }, onClick = { /* navigate */ })
                }
            }
        }
    )
}

Важно задать contentDescription для каждой иконки — это требование accessibility. Без описания TalkBack не озвучит кнопку. Для чисто декоративных элементов используйте contentDescription = null.

TopAppBar в Material3: Dynamic Color и адаптация

Material3 (M3) — текущая версия Material Design, рекомендованная Google для новых проектов. TopAppBar в M3 реализован через TopAppBar, CenterAlignedTopAppBar и MediumTopAppBar. Ключевое отличие от Material2 — встроенная поддержка dynamic color, адаптивной высоты и scroll behavior.

Dynamic Color автоматически подбирает цвета панели на основе обоев устройства (Android 12+). TopAppBar в M3 использует surfaceColor для фона и primary для заголовка. Если dynamic color недоступна, применяется fallback-палитра из MaterialTheme. По данным Google Material Design (2025), 63% пользователей Android 12+ используют dynamic color в приложениях.

MediumTopAppBar — расширенный вариант с крупным заголовком (32 sp), который при прокрутке плавно уменьшается до 20 sp, превращаясь в SmallTopAppBar. Этот эффект реализуется через TopAppBarDefaults.mediumTopAppBarColors() и параметр scrollBehavior. Анимация перехода контролируется через TopAppBarState, который отслеживает коллапс заголовка.

kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MediumTopBarExample() {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
    Scaffold(
        topBar = {
            MediumTopAppBar(
                title = { Text("Library") },
                navigationIcon = {
                    IconButton(onClick = { }) {
                        Icon(Icons.Filled.Menu, contentDescription = "Menu")
                    }
                },
                scrollBehavior = scrollBehavior
            )
        }
    ) { padding ->
        LazyColumn(contentPadding = padding) { /* content */ }
    }
}

Для Material3 TopAppBar обязательно использовать @OptIn(ExperimentalMaterial3Api::class) — аннотация указывает, что API может измениться в будущих версиях. На момент 2025 года TopAppBar в M3 остаётся experimental, но Google рекомендует его для продакшена с соответствующей проверкой.

ScrollBehavior: скрытие панели при прокрутке

ScrollBehavior — механизм, управляющий видимостью TopAppBar при вертикальной прокрутке контента. В Jetpack Compose scrollBehavior позволяет скрыть или уменьшить панель для освобождения места, что особенно полезно на экранах с большим списком контента.

Material3 предоставляет три стратегии: enterAlways (панель появляется при скролле вверх и скрывается при скролле вниз), exitUntilCollapsed (панель скрывается только после полного коллапса заголовка) и кастомная через реализацию интерфейса TopAppBarScrollBehavior. Первый вариант подходит для лент контента, второй — для экранов с MediumTopAppBar.

ScrollBehavior требует координации с LazyColumn или LazyRow через rememberLazyListState(). Состояние скролла передаётся в TopAppBar через параметр scrollBehavior. Компонент автоматически подписывается на события скролла и анимирует видимость панели. По данным Android Developers (2025), enterAlwaysScrollBehavior — наиболее популярная стратегия, используемая в 75% приложений с прокручиваемым TopAppBar.

Настройка кастомного ScrollBehavior

Для создания кастомного поведения наследуйтесь от TopAppBarScrollBehavior и переопределите методы onScroll и onDrag. Кастомный behaviour полезен, когда стандартные сценарии не покрывают требования дизайна — например, панель должна скрываться только после превышения определённого порога скролла.

По умолчанию scrollBehavior не добавляет отступ для контента — paddingTop нужно задавать вручную через contentPadding в Scaffold или через Modifier.padding в LazyColumn. В MediumTopAppBar отступы автоматически рассчитываются через TopAppBarState.collapsedFraction.

kotlin
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    topBar = {
        MediumTopAppBar(
            title = { Text("Content") },
            scrollBehavior = scrollBehavior
        )
    }
) { padding ->
    LazyColumn(contentPadding = padding) { /* items */ }
}

ScrollBehavior доступен только в Material3. В Material2 TopAppBar не имеет встроенной поддержки скрытия при скролле — для аналогичного поведения требуется ручная реализация через NestedScrollConnection.

Часто задаваемые вопросы

Чем отличается TopAppBar от Toolbar в Android?

TopAppBar — это Compose-реализация App Bar, работающая декларативно через composable-функции. Toolbar — View-компонент из XML-вёрстки. TopAppBar автоматически подстраивается под тему Compose, поддерживает slot API и не требует findViewById, в отличие от Toolbar, который управляется через код Activity.

Как убрать тень у TopAppBar?

В Material3 тень отсутствует по умолчанию — TopAppBar использует поверхностный цвет (surface) вместо elevation. В Material2 тень убирается установкой параметра elevation = 0.dp. Дополнительно можно вызвать Modifier.shadow(0.dp) для полного отключения.

Как добавить строку поиска в TopAppBar?

Передайте composable-блок с TextField в параметр title. При активации поиска скройте navigationIcon и actions через условный рендеринг. Состояние храните через remember: var isSearching by remember { mutableStateOf(false) }. При isSearching = true в title рендерится TextField вместо Text.

Поддерживает ли TopAppBar двухстрочный заголовок?

Да, через кастомный composable в параметр title. Вместо одного Text передайте Column с двумя Text: первый — основной заголовок (semibold), второй — подзаголовок (medium, меньший размер). MediumTopAppBar имеет встроенную поддержку двухстрочного заголовка с анимацией коллапса.

Почему TopAppBar накладывается на статус-бар?

TopAppBar не учитывает системные отступы автоматически. Необходимо применить Modifier.statusBarsPadding() к TopAppBar или использовать Scaffold, который обрабатывает WindowInsets. В Material3 добавлен windowInsets параметр для автоматического учёта системных полей.

Итоги

  • TopAppBar — основной компонент верхней панели в Jetpack Compose, реализованный через slot API с title, navigationIcon и actions
  • Material3 предоставляет три варианта: SmallTopAppBar, CenterAlignedTopAppBar и MediumTopAppBar с поддержкой dynamic color
  • NavigationIcon используется для открытия Drawer или возврата, а действия (actions) — для контекстных иконок
  • ScrollBehavior управляет видимостью TopAppBar при прокрутке через enterAlways и exitUntilCollapsed стратегии
  • DropdownMenu позволяет разместить переполненные экшены в выпадающем меню с иконкой MoreVert
  • Dynamic Color автоматически адаптирует цвета TopAppBar под обои устройства на Android 12+
  • Для предотвращения наложения на статус-бар используйте Modifier.statusBarsPadding() или параметр windowInsets в M3

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также