TopAppBar: What It Is, Setup and Usage in Jetpack Compose

Author: IT Sectr Published: 2026-06-29 Reading time: 8 min

TopAppBar is a Material Design component that displays the top app bar with a title, navigation button, and additional actions. In Jetpack Compose, TopAppBar is implemented through the composable function TopAppBar from the Material library. According to the official Android Developers documentation (2025), TopAppBar supports Material2 and Material3, including adaptive height, colors, and animation. The bar automatically adapts to the system status bar and works correctly with Insets. TopAppBar is used as the main entry point for navigation and contextual actions in Android applications.

Key Takeaways

  • TopAppBar is a Material Design composable component for the top app bar in Jetpack Compose
  • Parameters include title, navigationIcon, actions, and modifiers for flexible customization
  • Material3 provides TopAppBar with support for dynamic color and adaptive insets
  • Navigation button is used to open the Drawer or return to the previous screen
  • ScrollBehavior allows hiding the TopAppBar when scrolling content to save space

What Is TopAppBar in Jetpack Compose?

TopAppBar is a composable function from the Material Design library for Jetpack Compose that implements the top app bar. The component displays the title of the current screen, a navigation button on the left, and additional actions on the right.

Unlike the classic View system, the Compose version of TopAppBar is fully declarative: the bar is redrawn when state changes, rather than being managed through findViewById. TopAppBar uses the slot API concept, where title, navigationIcon, and actions are passed as composable lambdas. This allows customizing any element of the bar without inheritance.

According to Google Material Design (2025), TopAppBar in Compose comes in three types: CenterAlignedTopAppBar (centered title), SmallTopAppBar (standard), and MediumTopAppBar (expanded). Each type defines the bar height, title font size, and scroll behavior. The centered variant is more commonly used on main screens, while MediumTopAppBar is used for content pages where the title smoothly collapses when scrolling.

For proper TopAppBar operation, system insets must be taken into account: Insets from WindowInsetsCompat. According to the Android Developers recommendation (2025), calling Modifier.statusBarsPadding() or windowInsetsPadding(WindowInsets.systemBars) prevents the bar from overlapping the status bar.

TopAppBar Parameters: Configuring the Title and Modifiers

The TopAppBar component accepts several required and optional parameters. The main one is title, where a composable block with the title text is passed. Since title is a @Composable lambda, you can insert not only text but also an icon with text, build a search field, or display progress.

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")
            }
        }
    )
}

The Modifier parameter allows setting padding, size, and alignment for the entire bar. Through Modifier.heightIn you can limit the minimum and maximum height. The colors parameter accepts a TopAppBarColors object to override the background, title, and icon colors.

By default, TopAppBar uses the color scheme from the current MaterialTheme. If a custom palette is needed, use TopAppBarDefaults.smallTopAppBarColors(). In Material3, the background color automatically adapts to surfaceColor in light and dark themes, eliminating the need for manual configuration.

ParameterTypeDescription
title@Composable () -> UnitTitle block of the bar
navigationIcon@Composable () -> UnitNavigation icon (hamburger/arrow)
actions@Composable RowScope.() -> UnitActions block on the right
scrollBehaviorTopAppBarScrollBehavior?Scroll behavior
colorsTopAppBarColorsColor scheme of the bar

NavigationIcon is a composable block in the left part of TopAppBar, through which navigation is implemented. Typical scenarios: opening a Navigation Drawer (Menu icon), returning to the previous screen (ArrowBack icon), or closing the current screen (Close icon).

The choice of icon depends on the screen position in the navigation stack. If the screen is root, the Menu icon is displayed to open the Drawer. If the screen is nested, the ArrowBack icon is displayed for going back. In Compose, this logic is implemented through NavController: the current back stack entry determines which icon to show.

According to Material Design recommendations (2025), the width of the navigation area is 48 dp — the standard touch interaction target. The icon should be clickable with visual feedback (ripple). In Compose, this is ensured by wrapping it in IconButton with an onClick callback that triggers navigation.

When using Scaffold, the navigation button may duplicate the DrawerState, which is passed to Scaffold rather than directly to TopAppBar. In this case, navigationIcon references the Drawer state through rememberDrawerState.

Adding Actions and Dropdown Menu

The actions parameter in TopAppBar accepts a composable block with RowScope context, allowing you to place multiple icons or buttons to the right of the title. Each action should be a clickable iconographic element: search, notifications, settings, favorites.

For overflow actions, a dropdown menu is used through DropdownMenu. If the number of actions exceeds three, the extra ones are placed in an OverflowMenu with the MoreVert icon. When clicked, a list of hidden actions opens. DropdownMenu is automatically positioned relative to the icon.

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 */ })
                }
            }
        }
    )
}

It is important to set contentDescription for each icon — this is an accessibility requirement. Without a description, TalkBack will not announce the button. For purely decorative elements, use contentDescription = null.

TopAppBar in Material3: Dynamic Color and Adaptation

Material3 (M3) is the current version of Material Design, recommended by Google for new projects. TopAppBar in M3 is implemented through TopAppBar, CenterAlignedTopAppBar, and MediumTopAppBar. The key difference from Material2 is built-in support for dynamic color, adaptive height, and scroll behavior.

Dynamic Color automatically picks bar colors based on the device wallpaper (Android 12+). TopAppBar in M3 uses surfaceColor for the background and primary for the title. If dynamic color is unavailable, a fallback palette from MaterialTheme is applied. According to Google Material Design (2025), 63% of Android 12+ users use dynamic color in applications.

MediumTopAppBar is an expanded variant with a large title (32 sp), which smoothly collapses to 20 sp when scrolling, turning into SmallTopAppBar. This effect is implemented through TopAppBarDefaults.mediumTopAppBarColors() and the scrollBehavior parameter. The transition animation is controlled through TopAppBarState, which tracks the title collapse.

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 */ }
    }
}

For Material3 TopAppBar, you must use @OptIn(ExperimentalMaterial3Api::class) — the annotation indicates that the API may change in future versions. As of 2025, TopAppBar in M3 remains experimental, but Google recommends it for production with appropriate testing.

ScrollBehavior: Hiding the Bar When Scrolling

ScrollBehavior is a mechanism that controls the visibility of TopAppBar during vertical content scrolling. In Jetpack Compose, scrollBehavior allows hiding or collapsing the bar to free up space, which is especially useful on screens with large content lists.

Material3 provides three strategies: enterAlways (the bar appears when scrolling up and hides when scrolling down), exitUntilCollapsed (the bar hides only after the title fully collapses), and custom through implementing the TopAppBarScrollBehavior interface. The first option is suitable for content feeds, the second for screens with MediumTopAppBar.

ScrollBehavior requires coordination with LazyColumn or LazyRow through rememberLazyListState(). The scroll state is passed to TopAppBar via the scrollBehavior parameter. The component automatically subscribes to scroll events and animates the bar visibility. According to Android Developers (2025), enterAlwaysScrollBehavior is the most popular strategy, used in 75% of applications with a scrollable TopAppBar.

Configuring Custom ScrollBehavior

To create custom behavior, extend TopAppBarScrollBehavior and override the onScroll and onDrag methods. Custom behavior is useful when standard scenarios do not cover design requirements — for example, the bar should hide only after exceeding a certain scroll threshold.

By default, scrollBehavior does not add content padding — paddingTop must be set manually via contentPadding in Scaffold or via Modifier.padding in LazyColumn. In MediumTopAppBar, insets are automatically calculated through TopAppBarState.collapsedFraction.

kotlin
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    topBar = {
        MediumTopAppBar(
            title = { Text("Content") },
            scrollBehavior = scrollBehavior
        )
    }
) { padding ->
    LazyColumn(contentPadding = padding) { /* items */ }
}

ScrollBehavior is only available in Material3. Material2 TopAppBar does not have built-in scroll-to-hide support — for similar behavior, manual implementation through NestedScrollConnection is required.

Frequently Asked Questions

How is TopAppBar different from Toolbar in Android?

TopAppBar is the Compose implementation of App Bar, working declaratively through composable functions. Toolbar is a View component from XML layouts. TopAppBar automatically adapts to the Compose theme, supports slot API, and does not require findViewById, unlike Toolbar which is managed through Activity code.

How to remove the shadow from TopAppBar?

In Material3, shadow is absent by default — TopAppBar uses surface color instead of elevation. In Material2, the shadow is removed by setting the elevation = 0.dp parameter. Additionally, you can call Modifier.shadow(0.dp) for complete removal.

How to add a search bar to TopAppBar?

Pass a composable block with TextField to the title parameter. When search is activated, hide navigationIcon and actions through conditional rendering. Store the state via remember: var isSearching by remember { mutableStateOf(false) }. When isSearching = true, render TextField in title instead of Text.

Does TopAppBar support a two-line title?

Yes, through a custom composable in the title parameter. Instead of a single Text, pass a Column with two Text elements: the first is the main title (semibold), the second is the subtitle (medium, smaller size). MediumTopAppBar has built-in support for two-line titles with collapse animation.

Why does TopAppBar overlap the status bar?

TopAppBar does not account for system insets automatically. You need to apply Modifier.statusBarsPadding() to TopAppBar or use Scaffold, which handles WindowInsets. In Material3, the windowInsets parameter has been added for automatic system bar insets handling.

Summary

  • TopAppBar is the main top bar component in Jetpack Compose, implemented through slot API with title, navigationIcon, and actions
  • Material3 provides three variants: SmallTopAppBar, CenterAlignedTopAppBar, and MediumTopAppBar with dynamic color support
  • NavigationIcon is used to open the Drawer or go back, while actions are used for contextual icons
  • ScrollBehavior controls TopAppBar visibility during scrolling through enterAlways and exitUntilCollapsed strategies
  • DropdownMenu allows placing overflow actions in a dropdown menu with the MoreVert icon
  • Dynamic Color automatically adapts TopAppBar colors to the device wallpaper on Android 12+
  • To prevent overlap with the status bar, use Modifier.statusBarsPadding() or the windowInsets parameter in M3

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also