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, що реалізує верхню панель застосунку. Компонент відображає заголовок поточного екрана, навігаційну кнопку зліва та додаткові дії справа.

На відміну від класичної 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(WindowInsets.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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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