TopAppBar é um componente do Material Design que exibe a barra superior do aplicativo com um título, botão de navegação e ações adicionais. No Jetpack Compose, o TopAppBar é implementado através da função composable TopAppBar da biblioteca Material. De acordo com a documentação oficial do Android Developers (2025), o TopAppBar suporta Material2 e Material3, incluindo altura adaptativa, cores e animação. A barra se adapta automaticamente à barra de status do sistema e funciona corretamente com Insets. O TopAppBar é usado como ponto de entrada principal para navegação e ações contextuais em aplicativos Android.
Pontos principais
TopAppBar é uma função composable da biblioteca Material Design para Jetpack Compose que implementa a barra superior do aplicativo. O componente exibe o título da tela atual, um botão de navegação à esquerda e ações adicionais à direita.
Ao contrário do sistema clássico de View, a versão Compose do TopAppBar é totalmente declarativa: a barra é redesenhada quando o estado muda, em vez de ser gerenciada através de findViewById. O TopAppBar usa o conceito de slot API, onde title, navigationIcon e actions são passados como lambdas composables. Isso permite personalizar qualquer elemento da barra sem herança.
De acordo com o Google Material Design (2025), o TopAppBar no Compose vem em três tipos: CenterAlignedTopAppBar (título centralizado), SmallTopAppBar (padrão) e MediumTopAppBar (expandido). Cada tipo define a altura da barra, o tamanho da fonte do título e o comportamento de rolagem. A variante centralizada é mais usada em telas principais, enquanto o MediumTopAppBar é usado para páginas de conteúdo onde o título diminui suavemente ao rolar.
Para o funcionamento correto do TopAppBar, é necessário considerar as margens do sistema: Insets do WindowInsetsCompat. De acordo com a recomendação do Android Developers (2025), chamar Modifier.statusBarsPadding() ou windowInsetsPadding(WindowInsets.systemBars) impede que a barra se sobreponha à barra de status.
O componente TopAppBar aceita vários parâmetros obrigatórios e opcionais. O principal é title, onde um bloco composable com o texto do título é passado. Como title é uma lambda @Composable, você pode inserir não apenas texto, mas também um ícone com texto, criar um campo de busca ou exibir progresso.
@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")
}
}
)
}
O parâmetro Modifier permite definir preenchimento, tamanho e alinhamento para toda a barra. Através do Modifier.heightIn, é possível limitar a altura mínima e máxima. O parâmetro colors aceita um objeto TopAppBarColors para substituir as cores de fundo, título e ícones.
Por padrão, o TopAppBar usa o esquema de cores do MaterialTheme atual. Se uma paleta personalizada for necessária, use TopAppBarDefaults.smallTopAppBarColors(). No Material3, a cor de fundo se adapta automaticamente ao surfaceColor em temas claro e escuro, eliminando a necessidade de configuração manual.
| Parâmetro | Tipo | Descrição |
|---|---|---|
| title | @Composable () -> Unit | Bloco do título da barra |
| navigationIcon | @Composable () -> Unit | Ícone de navegação (hambúrguer/seta) |
| actions | @Composable RowScope.() -> Unit | Bloco de ações à direita |
| scrollBehavior | TopAppBarScrollBehavior? | Comportamento de rolagem |
| colors | TopAppBarColors | Esquema de cores da barra |
NavigationIcon é um bloco composable na parte esquerda do TopAppBar através do qual a navegação é implementada. Cenários típicos: abrir um Navigation Drawer (ícone Menu), retornar à tela anterior (ícone SetaVoltar) ou fechar a tela atual (ícone Fechar).
A escolha do ícone depende da posição da tela na pilha de navegação. Se a tela for raiz, o ícone de Menu é exibido para abrir o Drawer. Se a tela estiver aninhada, o ícone de SetaVoltar é exibido para voltar. No Compose, essa lógica é implementada através do NavController: a entrada atual da back stack determina qual ícone mostrar.
De acordo com as recomendações do Material Design (2025), a largura da área de navegação é de 48 dp, o alvo padrão para interação por toque. O ícone deve ser clicável com feedback visual (ripple). No Compose, isso é garantido envolvendo-o em IconButton com um callback onClick que aciona a navegação.
Ao usar Scaffold, o botão de navegação pode duplicar o DrawerState, que é passado para o Scaffold em vez de diretamente para o TopAppBar. Nesse caso, navigationIcon referencia o estado do Drawer através de rememberDrawerState.
O parâmetro actions no TopAppBar aceita um bloco composable com contexto RowScope, permitindo colocar vários ícones ou botões à direita do título. Cada ação deve ser um elemento iconográfico clicável: pesquisa, notificações, configurações, favoritos.
Para ações excedentes, um menu suspenso é usado através de DropdownMenu. Se o número de ações exceder três, as extras são colocadas em um OverflowMenu com o ícone MoreVert. Ao clicar, uma lista de ações ocultas é aberta. O DropdownMenu é posicionado automaticamente em relação ao ícone.
@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 */ })
}
}
}
)
}
É importante definir contentDescription para cada ícone — isso é um requisito de acessibilidade. Sem descrição, o TalkBack não anunciará o botão. Para elementos puramente decorativos, use contentDescription = null.
Material3 (M3) é a versão atual do Material Design, recomendada pelo Google para novos projetos. O TopAppBar no M3 é implementado através de TopAppBar, CenterAlignedTopAppBar e MediumTopAppBar. A principal diferença do Material2 é o suporte integrado para cor dinâmica, altura adaptativa e comportamento de rolagem.
A Cor Dinâmica seleciona automaticamente as cores da barra com base no papel de parede do dispositivo (Android 12+). O TopAppBar no M3 usa surfaceColor para o fundo e primary para o título. Se a cor dinâmica não estiver disponível, uma paleta alternativa do MaterialTheme é aplicada. De acordo com o Google Material Design (2025), 63% dos usuários do Android 12+ usam cor dinâmica em aplicativos.
MediumTopAppBar é uma variante expandida com um título grande (32 sp), que diminui suavemente para 20 sp ao rolar, transformando-se em SmallTopAppBar. Este efeito é implementado através de TopAppBarDefaults.mediumTopAppBarColors() e do parâmetro scrollBehavior. A animação de transição é controlada através de TopAppBarState, que rastreia a contração do título.
@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 */ }
}
}
Para o TopAppBar do Material3, é necessário usar @OptIn(ExperimentalMaterial3Api::class) — a anotação indica que a API pode mudar em versões futuras. A partir de 2025, o TopAppBar no M3 continua experimental, mas o Google o recomenda para produção com os testes apropriados.
ScrollBehavior é um mecanismo que controla a visibilidade do TopAppBar durante a rolagem vertical do conteúdo. No Jetpack Compose, o scrollBehavior permite ocultar ou contrair a barra para liberar espaço, o que é especialmente útil em telas com grandes listas de conteúdo.
O Material3 fornece três estratégias: enterAlways (a barra aparece ao rolar para cima e oculta ao rolar para baixo), exitUntilCollapsed (a barra só oculta após o título colapsar completamente) e personalizada através da implementação da interface TopAppBarScrollBehavior. A primeira opção é adequada para feeds de conteúdo, a segunda para telas com MediumTopAppBar.
O ScrollBehavior requer coordenação com LazyColumn ou LazyRow através de rememberLazyListState(). O estado de rolagem é passado para o TopAppBar através do parâmetro scrollBehavior. O componente se inscreve automaticamente nos eventos de rolagem e anima a visibilidade da barra. De acordo com o Android Developers (2025), enterAlwaysScrollBehavior é a estratégia mais popular, usada em 75% dos aplicativos com TopAppBar rolável.
Para criar um comportamento personalizado, estenda TopAppBarScrollBehavior e sobrescreva os métodos onScroll e onDrag. O comportamento personalizado é útil quando os cenários padrão não cobrem os requisitos de design — por exemplo, quando a barra deve ocultar apenas após exceder um certo limite de rolagem.
Por padrão, o scrollBehavior não adiciona preenchimento ao conteúdo; paddingTop deve ser definido manualmente via contentPadding no Scaffold ou via Modifier.padding no LazyColumn. No MediumTopAppBar, as margens são calculadas automaticamente através de TopAppBarState.collapsedFraction.
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Content") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
O ScrollBehavior está disponível apenas no Material3. O TopAppBar do Material2 não tem suporte integrado para ocultar ao rolar — para comportamento semelhante, é necessária implementação manual através de NestedScrollConnection.
Perguntas frequentes
TopAppBar é a implementação Compose da App Bar, funcionando declarativamente através de funções composables. Toolbar é um componente View de layouts XML. O TopAppBar se adapta automaticamente ao tema do Compose, suporta slot API e não requer findViewById, ao contrário do Toolbar que é gerenciado através do código da Activity.
No Material3, a sombra está ausente por padrão — o TopAppBar usa a cor de superfície em vez de elevation. No Material2, a sombra é removida definindo o parâmetro elevation = 0.dp. Adicionalmente, pode-se chamar Modifier.shadow(0.dp) para remoção completa.
Passe um bloco composable com TextField para o parâmetro title. Ao ativar a pesquisa, oculte navigationIcon e actions através de renderização condicional. Armazene o estado através de remember: var isSearching by remember { mutableStateOf(false) }. Quando isSearching = true, renderize TextField no title em vez de Text.
Sim, através de um composable personalizado no parâmetro title. Em vez de um único Text, passe uma Column com dois elementos Text: o primeiro é o título principal (semibold), o segundo é o subtítulo (medium, tamanho menor). O MediumTopAppBar tem suporte integrado para títulos de duas linhas com animação de colapso.
O TopAppBar não leva em conta as margens do sistema automaticamente. É necessário aplicar Modifier.statusBarsPadding() ao TopAppBar ou usar Scaffold, que gerencia WindowInsets. No Material3, o parâmetro windowInsets foi adicionado para o gerenciamento automático das margens do sistema.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também