How to Implement Jetpack Compose TopAppBar?

Jetpack Compose topappbar

In this article, we will learn how to implement TopAppBar in Android Jetpack Compose. If you are familiar with XML layouts, it is the Toolbar.

Prerequisites:

Jetpack Compose TopAppBar:

It provides the information about the content and actions related to the current screen. It’s used for branding, screen titles, navigation, and actions.

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.

modifierThe 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.

Here is a simple example:

@Composable
fun MyUI() {
    TopAppBar(
        title = {
            Text(text = "SemicolonSpace")
        }
    )
}

Output:

TopAppBar Example

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:

  1. Display a menu icon to open the navigation drawer.
  2. An arrow icon for the back button.

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:

Navigation Icon

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:

Back Icon

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:

Actions

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.

Jetpack Compose topappbar menu

Custom Top App Bar:

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:

Jetpack Compose TopAppBar Center Title

This is all about TopAppBar in Jetpack Compose. I hope you have learned new things. If you have any doubts, comment below.

Continue Exploring Jetpack Compose:

References:

Leave a Comment