Jetpack Compose

A Visual Guide to TopAppBar Variants in Jetpack Compose

Material 3 offers a variety of pre-built TopAppBar components to streamline your development and ensure consistency with Material Design guidelines. This article explores different TopAppBar variations, including those with centered titles, expandable layouts, and support for subtitles.
Alex Zhukovich 3 min read
A Visual Guide to TopAppBar Variants in Jetpack Compose

The TopAppBar is a commonly used component in Jetpack Compose as many screens use it. While developers commonly customize the TopAppBar. Material 3 library provides predefined variations to simplify development and follow Material Design guidelines.

In this article, we will explore:

  • The different TopAppBar components offered by the Material 3 library.
  • The default typography and height in each TopAppBar variant.
đź’ˇ
This article focuses on TopAppBar variations with consistent title, navigation icons and actions. All expandable/collapsable components will have a consistent scrolling experience.

Let’s look at the default text styles for titles and subtitles, as well as the component height, to help choose the best TopAppBar components for your design and use case. These parameters can also be customized.

For easy comparison, I created a comprehensive table summarizing all the available options. Below, you’ll find detailed information about each TopAppBar variant, alongside with a basic example.

TopAppBar

The TopAppBar is the most widespread component.

0:00
/0:05
Default values:
TopAppBar
Title Text Style TitleLarge
Height 64dp
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun Demo_TopAppBar() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Title") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.AutoMirrored.Default.ArrowBack, "Back")
                    }
                },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.AttachFile, "Attach")
                    }
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.MoreVert, "More")
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            Text(
                modifier = Modifier.padding(16.dp),
                text = remember { LoremIpsum().values.first() },
                fontSize = 16.sp
            )
        }
    }
}

CenterAlignedTopAppBar

Similar to the standard TopAppBar, but with one key difference: the title is horizontally centered.

0:00
/0:05
Default values:
CenterAlignedTopAppBar
Title Text Style TitleLarge
Height 64dp
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun Demo_CenterAlignedTopAppBar() {
    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = { Text("Title") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.AutoMirrored.Default.ArrowBack, "Back")
                    }
                },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.AttachFile, "Attach")
                    }
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.MoreVert, "More")
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            Text(
                modifier = Modifier.padding(16.dp),
                text = remember { LoremIpsum().values.first() },
                fontSize = 16.sp
            )
        }
    }
}

MediumTopAppBar and LargeTopAppBar

These components introduce dynamic behavior, allowing the components to expand and collapse. They can display titles, navigation icons, and actions.

0:00
/0:11
Default values:
MediumTopAppBar LargeTopAppBar
Title Text Style (Collapsed) TitleLarge TitleLarge
Title Text Style (Expanded) HeadlineSmall HeadlineMedium
Collapsed Height 64dp 64dp
Expanded Height 112dp 152dp
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun Demo_MediumTopAppBar() {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            MediumTopAppBar(
                title = { Text("Title") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.AutoMirrored.Default.ArrowBack, "Back")
                    }
                },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.AttachFile, "Attach")
                    }
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.MoreVert, "More")
                    }
                },
                scrollBehavior = scrollBehavior
            )
        }
    ) { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            Text(
                modifier = Modifier.padding(16.dp),
                text = remember { LoremIpsum().values.first() },
                fontSize = 16.sp
            )
        }
    }
}

MediumFlexibleTopAppBar and LargeFlexibleTopAppBar

These components add the capability to display subtitle alongside with titles, navigation icons, and actions.

0:00
/0:10
Default values:
MediumFlexibleTopAppBar LargeFlexibleTopAppBar
Title Text Style (Collapsed) TitleLarge TitleLarge
Title Text Style (Expanded) HeadlineMedium DisplaySmall
Subtitle Text Style (Collapsed) LabelMedium LabelMedium
Subtitle Text Style (Expanded) LabelLarge TitleMedium
Collapsed Height 64dp 64dp
Expanded Height (with subtitle) 136dp 152dp
Expanded Height (without subtitle) 112dp 120dp
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Preview
@Composable
fun Demo_MediumFlexibleTopAppBar() {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            MediumFlexibleTopAppBar(
                title = { Text("Title") },
                subtitle = { Text("Subtitle") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.AutoMirrored.Default.ArrowBack, "Back")
                    }
                },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.AttachFile, "Attach")
                    }
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.MoreVert, "More")
                    }
                },
                scrollBehavior = scrollBehavior
            )
        }
    ) { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            Text(
                modifier = Modifier.padding(16.dp),
                text = remember { LoremIpsum().values.first() },
                fontSize = 16.sp
            )
        }
    }
}

TwoRowsTopAppBar

This component also supports expanded and collapsed states. It includes title, subtitle, navigation icons, and actions. The TwoRowsTopAppBar component simplifies the management of different text strings for expanded and collapsed states compared to MediumFlexibleTopAppBar.

⚠️
The TwoRowsTopAppBar was added in version 1.4.0-alpha07.
0:00
/0:06
Default values:
TwoRowsTopAppBar
Title Text Style (Collapsed) TitleLarge
Title Text Style (Expanded) HeadlineMedium
Subtitle Text Style (Collapsed) LabelMedium
Subtitle Text Style (Expanded) LabelLarge
Collapsed Height 64dp
Expanded Height (with subtitle) 136dp
Expanded Height (without subtitle) 112dp
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun Demo_TwoRowsTopAppBar() {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            TwoRowsTopAppBar(
                title = { expanded ->
                    Text(
                        text = if (expanded) "Expanded Title" else "Collapsed Title",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                },
                subtitle = { expanded ->
                    Text(
                        text = if (expanded) "Expanded Subtitle" else "Collapsed Subtitle",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                },
                navigationIcon = {
                    IconButton(onClick = { /* doSomething() */ }) {
                        Icon(
                            imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                            contentDescription = "Localized description"
                        )
                    }
                },
                scrollBehavior = scrollBehavior
            )
        }
    ) { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            Text(
                modifier = Modifier.padding(16.dp),
                text = remember { LoremIpsum().values.first() },
                fontSize = 16.sp
            )
        }
    }
}

Conclusion

By exploring different TopAppBar variants, we've seen that Material 3 offers pre-built solutions for many common use cases.

Understanding these predefined options saves development time and effort. Instead of reinventing the wheel and customizing the basic TopAppBar for each use case, you can leverage the pre-built solutions provided by the Material 3 library.

The next time, explore the available options in the Material 3 library. It may save you time and you will already use a polished solution.

Share
Comments
More from Mobile development with Alex
Jetpack Compose: Divider
Jetpack Compose

Jetpack Compose: Divider

This article covers using and customizing the “Dividers” components from the "Material 2" and "Material 3" libraries in the Jetpack Compose. In addition to that, we will explore the difference between implementation of the Divider, HorizontalDivider and VerticalDivider.
Alex Zhukovich 4 min read
Jetpack Compose: Switch
Jetpack Compose

Jetpack Compose: Switch

This article covers creating and customizing the "Switch" component in Jetpack Compose for enabling/disabling features. It explores differences between "Material" and "Material 3" libraries, and how to interact with and verify the Switch component's state in UI tests.
Alex Zhukovich 8 min read

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Mobile development with Alex.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.