
In this article, we will learn how to implement TopAppBar in Jetpack Compose. If you are familiar with XML layouts, it is the Toolbar.
Prerequisites:
What is TopAppBar in Android Jetpack Compose?
The top app bar provides the information about the content and actions related to the current screen. It is used for branding, screen titles, navigation, and actions.
Example:

For this article, create a MyUI() composalbe in the MainActivity, and call it from the onCreate() method.
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.outlined.Lock
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Search
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
YourProjectNameTheme(darkTheme = false) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Column(
modifier = Modifier
.fillMaxSize()
) {
MyUI()
}
}
}
}
}
}
@Composable
private fun MyUI() {
}
We will write our code in the MyUI().
Jetpack Compose has a prebuilt TopAppBar() API.
@Composable
fun TopAppBar(
title: @Composable () -> Unit,
modifier: Modifier = Modifier,
navigationIcon: @Composable (() -> Unit)? = null,
actions: @Composable RowScope.() -> Unit = {},
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = AppBarDefaults.TopAppBarElevation
)
It takes multiple parameters:
title – Title to be displayed. We use the Text() composable.
modifier – The modifier to be applied.
navigationIcon – The navigation icon to be displayed at the start. This should typically be an IconButton or IconToggleButton.
actions – The actions displayed at the end. These are the icons that are arranged in a row.
backgroundColor – The background color for the TopAppBar. Use Color.Transparent to have no color.
contentColor – The preferred color for the children.
elevation – The shadow behind the app bar.
TopAppBar Example:
Here is a simple top app bar:
@Composable
fun MyUI() {
TopAppBar(
title = {
Text(text = "SemicolonSpace")
}
)
}
Output:

Related: Text in Jetpack Compose (with Examples)
Navigation Icon:
The navigationIcon parameter provides the functionality to add an icon at the start of the top app bar. Generally, there are two use cases:
- Display a menu icon to open the navigation drawer.
- An arrow icon for the back button.
1. Menu Icon:
You need to add material icon dependency to get the icons.
@Composable
fun MyUI() {
val contextForToast = LocalContext.current.applicationContext
TopAppBar(
title = {
Text(text = "SemicolonSpace")
},
navigationIcon = {
IconButton(onClick = {
Toast.makeText(contextForToast, "Navigation Icon Click", Toast.LENGTH_SHORT)
.show()
}) {
Icon(imageVector = Icons.Filled.Menu, contentDescription = "Navigation icon")
}
}
)
}
Output:

2. Back Button:
For the back icon, simply change the Menu to ArrowBack.
@Composable
fun MyUI() {
val contextForToast = LocalContext.current.applicationContext
TopAppBar(
title = {
Text(text = "SemicolonSpace")
},
navigationIcon = {
IconButton(onClick = {
Toast.makeText(contextForToast, "Back Icon Click", Toast.LENGTH_SHORT)
.show()
}) {
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = "Go Back")
}
}
)
}
Output:

Actions:
The actions parameter helps us to add icons at the end of the TopAppBar. By default, they are arranged in a row.
@Composable
fun MyUI() {
val contextForToast = LocalContext.current.applicationContext
TopAppBar(
title = {
Text(text = "SemicolonSpace")
},
actions = {
// search icon
TopAppBarActionButton(
imageVector = Icons.Outlined.Search,
description = "Search"
) {
Toast.makeText(contextForToast, "Search Click", Toast.LENGTH_SHORT)
.show()
}
// lock icon
TopAppBarActionButton(
imageVector = Icons.Outlined.Lock,
description = "Lock"
) {
Toast.makeText(contextForToast, "Lock Click", Toast.LENGTH_SHORT)
.show()
}
}
)
}
@Composable
fun TopAppBarActionButton(
imageVector: ImageVector,
description: String,
onClick: () -> Unit
) {
IconButton(onClick = {
onClick()
}) {
Icon(imageVector = imageVector, contentDescription = description)
}
}
Output:

TopAppBar with OverFlowMenu:
Currently, there is no support for the overflow menu. But, there is a work around. Jetpack Compose provides DropdownMenu. We can add it to the our app bar and adjust its position.
@Composable
fun MyUI() {
val contextForToast = LocalContext.current.applicationContext
var dropDownMenuExpanded by remember {
mutableStateOf(false)
}
TopAppBar(
title = {
Text(text = "SemicolonSpace")
},
actions = {
// search icon
TopAppBarActionButton(
imageVector = Icons.Outlined.Search,
description = "Search"
) {
Toast.makeText(contextForToast, "Search Click", Toast.LENGTH_SHORT)
.show()
}
// lock icon
TopAppBarActionButton(
imageVector = Icons.Outlined.Lock,
description = "Lock"
) {
Toast.makeText(contextForToast, "Lock Click", Toast.LENGTH_SHORT)
.show()
}
// options icon (vertical dots)
TopAppBarActionButton(imageVector = Icons.Outlined.MoreVert, description = "Options") {
// show the drop down menu
dropDownMenuExpanded = true
}
// drop down menu
DropdownMenu(
expanded = dropDownMenuExpanded,
onDismissRequest = {
dropDownMenuExpanded = false
},
// play around with these values
// to position the menu properly
offset = DpOffset(x = 10.dp, y = (-60).dp)
) {
// this is a column scope
// items are added vertically
DropdownMenuItem(onClick = {
Toast.makeText(contextForToast, "Refresh Click", Toast.LENGTH_SHORT)
.show()
dropDownMenuExpanded = false
}) {
Text("Refresh")
}
DropdownMenuItem(onClick = {
Toast.makeText(contextForToast, "Settings Click", Toast.LENGTH_SHORT)
.show()
dropDownMenuExpanded = false
}) {
Text("Settings")
}
DropdownMenuItem(onClick = {
Toast.makeText(contextForToast, "Send Feedback Click", Toast.LENGTH_SHORT)
.show()
dropDownMenuExpanded = false
}) {
Text("Send Feedback")
}
}
}
)
}
@Composable
fun TopAppBarActionButton(
imageVector: ImageVector,
description: String,
onClick: () -> Unit
) {
IconButton(onClick = {
onClick()
}) {
Icon(imageVector = imageVector, contentDescription = description)
}
}
Run the app and tap on the vertical dots icon. You will see the drop-down menu.

TopAppBar with Transparent Background:
We can make the top app bar transparent by setting Color.Transparent as the background color. But, you won’t be happy with the output.
@Composable
private fun MyUI() {
TopAppBar(
title = { Text(text = "SemicolonSpace") },
backgroundColor = Color.Transparent
)
}
Output:

There is an elevation around it. We can fix it in 2 ways:
1. Instead of setting Color.Transparent, set the background color. In the above case, it is white.
@Composable
private fun MyUI() {
TopAppBar(
title = { Text(text = "SemicolonSpace") },
backgroundColor = Color.White
)
}
Output:

2. Remove the elevation.
@Composable
private fun MyUI() {
TopAppBar(
title = { Text(text = "SemicolonSpace") },
backgroundColor = Color.Transparent,
elevation = 0.dp
)
}
Output:

Custom TopAppBar:
There is another overload of TopAppBar():
@Composable
fun TopAppBar(
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = AppBarDefaults.TopAppBarElevation,
contentPadding: PaddingValues = AppBarDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
)
It doesn’t provide slots for title, navigation icon, and trailing actions. It is used to create app bars with a custom layout. Let’s set the title at the center using it.
@Composable
fun MyUI() {
TopAppBar {
// this is row scope
// add your layout here
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "SemicolonSpace",
fontWeight = FontWeight.Bold,
fontSize = 20.sp
)
}
}
}
Output:

This is all about TopAppBar in Jetpack Compose. I hope you have learned new things. If you have any doubts, comment below.
Related Articles:
- Jetpack Compose Card (with Examples)
- How to Convert SVG to XML in Android Studio?
- Doughnut Chart using Jetpack Compose
References: