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 није доступна, примењује се fallback палета из 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође