TopAppBar este o componentă Material Design care afișează panoul superior al aplicației cu titlu, buton de navigare și acțiuni suplimentare. În Jetpack Compose, TopAppBar este implementat prin funcția composable TopAppBar din biblioteca Material. Conform documentației oficiale Android Developers (2025), TopAppBar suportă Material2 și Material3, inclusiv înălțime adaptivă, culori și animații. Panoul se ajustează automat la bara de stare a sistemului și funcționează corect cu Insets. TopAppBar este utilizat ca punct principal de intrare pentru navigare și acțiuni contextuale în aplicațiile Android.
Puncte cheie
TopAppBar este o funcție composable din biblioteca Material Design pentru Jetpack Compose care implementează panoul superior al aplicației (App Bar). Componenta afișează titlul ecranului curent, butonul de navigare în stânga și acțiuni suplimentare în dreapta.
Spre deosebire de sistemul clasic View, versiunea Compose a TopAppBar este complet declarativă: panoul se redesenează la schimbarea stării, nefiind gestionat prin findViewById. TopAppBar folosește conceptul de slot API, unde title, navigationIcon și actions sunt transmise ca lambda-uri composable. Acest lucru permite personalizarea oricărui element al panoului fără moștenire.
Conform Google Material Design (2025), TopAppBar în Compose există în trei tipuri: CenterAlignedTopAppBar (titlu centrat), SmallTopAppBar (standard) și MediumTopAppBar (extins). Fiecare tip determină înălțimea panoului, dimensiunea fontului titlului și comportamentul la derulare. Varianta centrată este folosită mai des pe ecranele principale, iar MediumTopAppBar pentru paginile cu conținut, unde titlul se micșorează treptat la derulare.
Pentru funcționarea corectă a TopAppBar trebuie luate în considerare marginile de sistem: Insets din WindowInsetsCompat. Conform recomandării Android Developers (2025), apelarea Modifier.statusBarsPadding() sau windowInsetsPadding(WindowInsets.systemBars) previne suprapunerea panoului peste bara de stare.
Componenta TopAppBar acceptă o serie de parametri obligatorii și opționali. Principalul este title, unde se transmite un bloc composable cu textul titlului. Deoarece title este o lambda @Composable, se poate insera nu doar text, ci și o pictogramă cu text, o bară de căutare sau o bară de progres.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppTopBar() {
TopAppBar(
title = { Text("Principal") },
navigationIcon = {
IconButton(onClick = { /* open drawer */ }) {
Icon(
Icons.Filled.Menu,
contentDescription = "Menu"
)
}
},
actions = {
IconButton(onClick = { /* search */ }) {
Icon(Icons.Filled.Search, contentDescription = "Search")
}
}
)
}
Parametrul Modifier permite setarea marginilor, dimensiunii și alinierii întregului panou. Prin Modifier.heightIn se poate limita înălțimea minimă și maximă. Parametrul colors acceptă un obiect TopAppBarColors pentru suprascrierea culorilor de fundal, titlu și pictograme.
Implicit, TopAppBar folosește schema de culori din tema curentă MaterialTheme. Dacă este necesară o paletă personalizată, utilizați TopAppBarDefaults.smallTopAppBarColors(). În Material3, culoarea de fundal se adaptează automat la surfaceColor în tema deschisă și întunecată, eliminând necesitatea configurării manuale.
| Parametru | Tip | Descriere |
|---|---|---|
| title | @Composable () -> Unit | Blocul titlului panoului |
| navigationIcon | @Composable () -> Unit | Pictograma de navigare (hamburger/săgeată) |
| actions | @Composable RowScope.() -> Unit | Blocul acțiunilor din dreapta |
| scrollBehavior | TopAppBarScrollBehavior? | Comportamentul la derulare |
| colors | TopAppBarColors | Schema de culori a panoului |
NavigationIcon este un bloc composable în partea stângă a TopAppBar prin care se implementează navigarea. Scenarii tipice: deschiderea Navigation Drawer (pictograma Menu), revenirea la ecranul anterior (pictograma ArrowBack) sau închiderea ecranului curent (pictograma Close).
Alegerea pictogramei depinde de poziția ecranului în stiva de navigare. Dacă ecranul este rădăcină — se afișează pictograma Menu pentru deschiderea Drawer. Dacă ecranul este imbricat — pictograma ArrowBack pentru revenire. În Compose, această logică este implementată prin NavController: intrarea curentă din stiva back stack determină ce pictogramă să afișeze.
Conform recomandării Material Design (2025), lățimea zonei de navigare este de 48 dp — ținta standard pentru interacțiunea tactilă. Pictograma trebuie să fie clicabilă cu feedback vizual (ripple). În Compose, acest lucru este asigurat prin împachetarea în IconButton cu un callback onClick care declanșează navigarea.
La utilizarea Scaffold, butonul de navigare poate duplica DrawerState care este transmis la Scaffold, nu direct la TopAppBar. În acest caz, navigationIcon face referire la starea Drawer prin rememberDrawerState.
Parametrul actions în TopAppBar acceptă un bloc composable cu contextul RowScope, permițând plasarea mai multor pictograme sau butoane în dreapta titlului. Fiecare acțiune trebuie să fie un element iconografic clicabil: căutare, notificări, setări, favorite.
Pentru acțiunile în exces se folosește meniul derulant prin DropdownMenu. Dacă numărul de acțiuni depășește trei, cele suplimentare sunt plasate în OverflowMenu cu pictograma MoreVert. La apăsare, se deschide lista acțiunilor ascunse. DropdownMenu se poziționează automat față de pictogramă.
@Composable
fun TopBarWithOverflow() {
var menuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text("Profil") },
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("Setări") }, onClick = { /* navigate */ })
DropdownMenuItem(text = { Text("Despre") }, onClick = { /* navigate */ })
}
}
}
)
}
Este important să setați contentDescription pentru fiecare pictogramă — aceasta este o cerință de accesibilitate. Fără descriere, TalkBack nu va anunța butonul. Pentru elementele pur decorative, utilizați contentDescription = null.
Material3 (M3) este versiunea curentă a Material Design, recomandată de Google pentru proiecte noi. TopAppBar în M3 este implementat prin TopAppBar, CenterAlignedTopAppBar și MediumTopAppBar. Diferența cheie față de Material2 — suportul integrat pentru dynamic color, înălțime adaptivă și scroll behavior.
Dynamic Color selectează automat culorile panoului pe baza tapetului dispozitivului (Android 12+). TopAppBar în M3 folosește surfaceColor pentru fundal și primary pentru titlu. Dacă dynamic color nu este disponibilă, se aplică paleta de rezervă din MaterialTheme. Conform Google Material Design (2025), 63% dintre utilizatorii Android 12+ folosesc dynamic color în aplicații.
MediumTopAppBar este varianta extinsă cu titlu mare (32 sp), care la derulare se micșorează treptat la 20 sp, transformându-se în SmallTopAppBar. Acest efect este realizat prin TopAppBarDefaults.mediumTopAppBarColors() și parametrul scrollBehavior. Animația de tranziție este controlată de TopAppBarState, care urmărește colapsarea titlului.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MediumTopBarExample() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Bibliotecă") },
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu, contentDescription = "Menu")
}
},
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* content */ }
}
}
Pentru Material3 TopAppBar trebuie să utilizați @OptIn(ExperimentalMaterial3Api::class) — adnotarea indică faptul că API-ul se poate schimba în versiunile viitoare. În 2025, TopAppBar în M3 rămâne experimental, dar Google îl recomandă pentru producție cu verificare corespunzătoare.
ScrollBehavior este mecanismul care gestionează vizibilitatea TopAppBar la derularea verticală a conținutului. În Jetpack Compose, scrollBehavior permite ascunderea sau micșorarea panoului pentru a elibera spațiu, ceea ce este util în special pe ecrane cu liste mari de conținut.
Material3 oferă trei strategii: enterAlways (panoul apare la derularea în sus și se ascunde la derularea în jos), exitUntilCollapsed (panoul se ascunde doar după colapsarea completă a titlului) și personalizată prin implementarea interfeței TopAppBarScrollBehavior. Prima variantă este potrivită pentru fluxuri de conținut, a doua — pentru ecrane cu MediumTopAppBar.
ScrollBehavior necesită coordonare cu LazyColumn sau LazyRow prin rememberLazyListState(). Starea de derulare este transmisă către TopAppBar prin parametrul scrollBehavior. Componenta se abonează automat la evenimentele de derulare și animează vizibilitatea panoului. Conform Android Developers (2025), enterAlwaysScrollBehavior este cea mai populară strategie, utilizată în 75% din aplicațiile cu TopAppBar derulabil.
Pentru a crea un comportament personalizat, moșteniți de la TopAppBarScrollBehavior și suprascrieți metodele onScroll și onDrag. Comportamentul personalizat este util când scenariile standard nu acoperă cerințele de design — de exemplu, panoul ar trebui să se ascundă doar după depășirea unui anumit prag de derulare.
Implicit, scrollBehavior nu adaugă margini pentru conținut — paddingTop trebuie setat manual prin contentPadding în Scaffold sau prin Modifier.padding în LazyColumn. În MediumTopAppBar, marginile sunt calculate automat prin TopAppBarState.collapsedFraction.
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Conținut") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
ScrollBehavior este disponibil doar în Material3. În Material2, TopAppBar nu are suport integrat pentru ascundere la derulare — pentru un comportament similar este necesară implementarea manuală prin NestedScrollConnection.
Întrebări frecvente
TopAppBar este implementarea App Bar în Compose, care funcționează declarativ prin funcții composable. Toolbar este o componentă View din layout XML. TopAppBar se adaptează automat la tema Compose, suportă slot API și nu necesită findViewById, spre deosebire de Toolbar, care este gestionat prin codul Activity.
În Material3, umbra lipsește implicit — TopAppBar folosește culoarea de suprafață (surface) în loc de elevation. În Material2, umbra se elimină setând parametrul elevation = 0.dp. Suplimentar, se poate apela Modifier.shadow(0.dp) pentru dezactivarea completă.
Transmiteți un bloc composable cu TextField în parametrul title. La activarea căutării, ascundeți navigationIcon și actions prin randare condiționată. Stocați starea prin remember: var isSearching by remember { mutableStateOf(false) }. Când isSearching = true, în title se randază TextField în loc de Text.
Da, printr-un composable personalizat în parametrul title. În loc de un singur Text, transmiteți un Column cu două Text: primul — titlul principal (semibold), al doilea — subtitlul (medium, dimensiune mai mică). MediumTopAppBar are suport integrat pentru titlu pe două rânduri cu animație de colapsare.
TopAppBar nu ia în considerare automat marginile de sistem. Trebuie să aplicați Modifier.statusBarsPadding() la TopAppBar sau să utilizați Scaffold, care gestionează WindowInsets. În Material3, a fost adăugat parametrul windowInsets pentru luarea automată în considerare a câmpurilor de sistem.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și