Jetpack Compose AppBars: From Basics to Advanced Scroll Behaviors
Jetpack Compose offers a flexible and powerful way to build UI in Android. One of the essential components in any Android app is the AppBar, which provides a consistent space for branding, screen titles, and actions. In this post, we’ll explore different types of AppBar components in Jetpack Compose:
TopAppBar
CenterAlignedTopAppBar
MediumTopAppBar
LargeTopAppBar
We’ll also see how to handle different scroll behaviors and understand when to use each AppBar variant. Additionally, we’ll look at the BottomAppBar
.
TopAppBar Variants
1. TopAppBar
The TopAppBar
is the standard AppBar that appears at the top of the screen. It’s commonly used for branding, navigation, and actions.
- Use Case: Use
TopAppBar
for most of your app screens where a standard height AppBar is sufficient to display the title and actions.
@Composable
fun StandardTopAppBar() {
TopAppBar(
title = { Text("Standard TopAppBar") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
}
)
}
2. CenterAlignedTopAppBar
The CenterAlignedTopAppBar
aligns the title in the center, which is useful for screens where the title should have prominence.
- Use Case: Use
CenterAlignedTopAppBar
for apps where the title needs to be emphasized, such as in media or content-heavy applications.
@Composable
fun CenterAlignedAppBar() {
CenterAlignedTopAppBar(
title = { Text("Center Aligned TopAppBar") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
}
)
}
3. MediumTopAppBar
The MediumTopAppBar
offers more vertical space than the standard AppBar, which is suitable for screens that need a bit more emphasis on the title or additional elements.
Use Case: Use MediumTopAppBar
for screens where the title needs to stand out more, such as in news apps or dashboards.
@Composable
fun MediumTopAppBarExample() {
MediumTopAppBar(
title = { Text("Medium TopAppBar") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
}
)
}
4. LargeTopAppBar
The LargeTopAppBar
provides even more vertical space, making it ideal for screens that require a large, prominent title.
- Use Case: Use
LargeTopAppBar
for primary screens or landing pages where the title or branding needs maximum emphasis, such as in profile screens or welcome pages.
@Composable
fun LargeTopAppBarExample() {
LargeTopAppBar(
title = { Text("Large TopAppBar") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
}
)
}
Scroll Behaviors
Jetpack Compose provides several scroll behaviors to make the AppBar react to user scroll actions, enhancing the interactivity and dynamic nature of the UI.
1. EnterAlwaysScrollBehavior
The enterAlwaysScrollBehavior
makes the AppBar reappear as soon as the user scrolls up. This is useful for providing quick access to the AppBar as soon as the user starts scrolling up.
- Use Case: Ideal for content-heavy screens where quick re-access to the AppBar is necessary.
@Composable
fun AppBarWithEnterAlwaysScrollBehavior() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
topBar = {
TopAppBar(
title = { Text("Enter Always Scroll Behavior") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
},
scrollBehavior = scrollBehavior
)
}
) {
LazyColumn(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) {
items(100) {
Text("Item #$it", modifier = Modifier.padding(16.dp))
}
}
}
}
2. ExitUntilCollapsedScrollBehavior
The exitUntilCollapsedScrollBehavior
allows the AppBar to collapse and hide until the user scrolls back up to the top of the list. This provides more screen real estate for the content while ensuring the AppBar is available when needed.
Use Case: Suitable for screens where more content space is needed, and the AppBar can be hidden when scrolling down.
@Composable
fun AppBarWithExitUntilCollapsedScrollBehavior() {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
TopAppBar(
title = { Text("Exit Until Collapsed Scroll Behavior") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
},
scrollBehavior = scrollBehavior
)
}
) {
LazyColumn(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) {
items(100) {
Text("Item #$it", modifier = Modifier.padding(16.dp))
}
}
}
}
3. PinnedScrollBehavior
The pinnedScrollBehavior
keeps the AppBar pinned at the top and does not react to scrolling. This behavior ensures that the AppBar is always visible, regardless of the user’s scrolling.
- Use Case: Best for screens where the AppBar should always be accessible, such as in apps with critical actions or persistent navigation elements.
@Composable
fun AppBarWithPinnedScrollBehavior() {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
topBar = {
TopAppBar(
title = { Text("Pinned Scroll Behavior") },
navigationIcon = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
},
actions = {
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Handle more action */ }) {
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
},
scrollBehavior = scrollBehavior
)
}
) {
LazyColumn(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) {
items(100) {
Text("Item #$it", modifier = Modifier.padding(16.dp))
}
}
}
}
BottomAppBar
The BottomAppBar
is a versatile component that appears at the bottom of the screen. It is typically used for navigation and key actions.
- Use Case: Use `BottomAppBar` for screens where navigation or key actions need to be easily accessible from the bottom of the screen, such as in apps with primary actions or bottom navigation bars.
@Composable
fun BottomAppBarExample() {
Scaffold(
bottomBar = {
BottomAppBar(
actions = {
IconButton(onClick = { /* Handle navigation icon click */ }) {
Icon(Icons.Default.Home, contentDescription = "Home")
}
IconButton(onClick = { /* Handle search action */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
},
floatingActionButton = {
FloatingActionButton(onClick = { /* Handle FAB click */ }) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
)
}
) {
// Content goes here
}
}
Conclusion
Jetpack Compose’s AppBar components offer a range of options to suit different design needs. From the standard TopAppBar
to the more prominent LargeTopAppBar
, you can choose the one that best fits your app’s requirements. Adding various scroll behaviors makes the UI more dynamic and interactive. The BottomAppBar
provides a convenient way to place actions and navigation at the bottom of the screen. By leveraging these components and behaviors, you can create a polished and professional Android app with ease.
Happy Composing !
Cheers !