TopAppBar е компонент на Material Design, който показва горния панел на приложението със заглавие, навигационен бутон и допълнителни действия. В Jetpack Compose TopAppBar се имплементира чрез composable функцията TopAppBar от библиотеката Material. Според официалната документация на Android Developers (2025), TopAppBar поддържа Material2 и Material3, включително адаптивна височина, цветове и анимация. Панелът автоматично се настройва към системната лента за състояние и работи коректно с Insets. TopAppBar се използва като основна входна точка за навигация и контекстни действия в Android приложения.
Основни неща
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(WindowInsets.systemBars) предотвратява застъпването на панела с лентата за състояние.
Компонентът TopAppBar приема редица задължителни и незадължителни параметри. Основният е title, където се предава composable блок с текста на заглавието. Тъй като title е @Composable ламбда, може да се вмъкне не само текст, но и икона с текст, лента за търсене или лента за напредък.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppTopBar() {
TopAppBar(
title = { Text("Основен") },
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 | Блок за действия отдясно |
| scrollBehavior | TopAppBarScrollBehavior? | Поведение при превъртане |
| colors | TopAppBarColors | Цветова схема на панела |
NavigationIcon е composable блок в лявата част на TopAppBar, чрез който се имплементира навигация. Типични сценарии: отваряне на Navigation Drawer (икона Menu), връщане към предишния екран (икона ArrowBack) или затваряне на текущия екран (икона Close).
Изборът на икона зависи от позицията на екрана в стека за навигация. Ако екранът е корен — се показва икона Menu за отваряне на Drawer. Ако екранът е вложен — икона ArrowBack за връщане. В Compose тази логика се имплементира чрез NavController: текущият запис в back stack определя коя икона да се покаже.
Според препоръката на Material Design (2025), ширината на навигационната област е 48 dp — стандартна цел за touch взаимодействие. Иконата трябва да може да се кликва с визуална обратна връзка (ripple). В Compose това се осигурява чрез обвиване в IconButton с onClick callback, който стартира навигацията.
При използване на Scaffold, навигационният бутон може да дублира DrawerState, който се предава на Scaffold, а не директно на TopAppBar. В този случай navigationIcon се позовава на състоянието на Drawer чрез rememberDrawerState.
Параметърът actions в TopAppBar приема composable блок с контекст RowScope, което позволява поставяне на множество икони или бутони отдясно на заглавието. Всяко действие трябва да бъде кликаем иконографски елемент: търсене, известия, настройки, любими.
За препълнени действия се използва падащо меню чрез DropdownMenu. Ако броят на действията надвишава три, излишните се поставят в OverflowMenu с икона MoreVert. При натискане се отваря списък със скрити действия. DropdownMenu автоматично се позиционира спрямо иконата.
@Composable
fun TopBarWithOverflow() {
var menuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text("Профил") },
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("Настройки") }, onClick = { /* navigate */ })
DropdownMenuItem(text = { Text("Относно") }, onClick = { /* navigate */ })
}
}
}
)
}
Важно е да зададете contentDescription за всяка икона — това е изискване за достъпност. Без описание TalkBack няма да озвучи бутона. За чисто декоративни елементи използвайте contentDescription = null.
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 не е налично, се прилага резервна палитра от MaterialTheme. Според Google Material Design (2025), 63% от потребителите на Android 12+ използват dynamic color в приложения.
MediumTopAppBar е разширен вариант с голямо заглавие (32 sp), което при превъртане постепенно се смалява до 20 sp, превръщайки се в SmallTopAppBar. Този ефект се реализира чрез TopAppBarDefaults.mediumTopAppBarColors() и параметъра scrollBehavior. Анимацията на прехода се контролира от TopAppBarState, който проследява свиването на заглавието.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MediumTopBarExample() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Библиотека") },
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 е механизъм, който управлява видимостта на TopAppBar при вертикално превъртане на съдържание. В Jetpack Compose scrollBehavior позволява скриване или смаляване на панела за освобождаване на място, което е особено полезно на екрани с голям списък от съдържание.
Material3 предлага три стратегии: enterAlways (панелът се появява при превъртане нагоре и се скрива при превъртане надолу), exitUntilCollapsed (панелът се скрива едва след пълното свиване на заглавието) и персонализирана чрез имплементиране на интерфейса TopAppBarScrollBehavior. Първият вариант е подходящ за потоци от съдържание, вторият — за екрани с MediumTopAppBar.
ScrollBehavior изисква координация с LazyColumn или LazyRow чрез rememberLazyListState(). Състоянието на превъртане се предава на TopAppBar чрез параметъра scrollBehavior. Компонентът автоматично се абонира за събития на превъртане и анимира видимостта на панела. Според Android Developers (2025), enterAlwaysScrollBehavior е най-популярната стратегия, използвана в 75% от приложенията с превъртаем TopAppBar.
За да създадете персонализирано поведение, наследете от TopAppBarScrollBehavior и презапишете методите onScroll и onDrag. Персонализираното поведение е полезно, когато стандартните сценарии не покриват изискванията на дизайна — например панелът трябва да се скрива само след преминаване на определен праг на превъртане.
По подразбиране scrollBehavior не добавя поле за съдържание — paddingTop трябва да се зададе ръчно чрез contentPadding в Scaffold или чрез Modifier.padding в LazyColumn. В MediumTopAppBar полетата се изчисляват автоматично чрез TopAppBarState.collapsedFraction.
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Съдържание") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
ScrollBehavior е достъпен само в Material3. В Material2 TopAppBar няма вградена поддръжка за скриване при превъртане — за подобно поведение се изисква ръчна имплементация чрез NestedScrollConnection.
Често задавани въпроси
TopAppBar е Compose имплементация на App Bar, която работи декларативно чрез composable функции. Toolbar е View компонент от XML оформление. TopAppBar автоматично се настройва към темата на Compose, поддържа slot API и не изисква findViewById, за разлика от Toolbar, който се управлява чрез код на Activity.
В Material3 сянка по подразбиране няма — TopAppBar използва цвят на повърхността (surface) вместо elevation. В Material2 сянката се премахва чрез задаване на параметъра elevation = 0.dp. Допълнително може да се извика Modifier.shadow(0.dp) за пълно изключване.
Предайте composable блок с TextField в параметъра title. При активиране на търсенето скрийте navigationIcon и actions чрез условно рендериране. Съхранявайте състоянието чрез remember: var isSearching by remember { mutableStateOf(false) }. Когато isSearching = true, в title се рендерира TextField вместо Text.
Да, чрез персонализиран composable в параметъра title. Вместо един Text предайте Column с два Text: първият — основно заглавие (semibold), вторият — подзаглавие (medium, по-малък размер). MediumTopAppBar има вградена поддръжка за двуредово заглавие с анимация на свиване.
TopAppBar не взема предвид автоматично системните полета. Трябва да приложите Modifier.statusBarsPadding() към TopAppBar или да използвате Scaffold, който обработва WindowInsets. В Material3 е добавен параметър windowInsets за автоматично отчитане на системните полета.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също