TwoRowsTopAppBar

Functions summary

Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
TwoRowsTopAppBar(
    title: @Composable (expanded: Boolean) -> Unit,
    modifier: Modifier,
    subtitle: (@Composable (expanded: Boolean) -> Unit)?,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    titleHorizontalAlignment: Alignment.Horizontal,
    collapsedHeight: Dp,
    expandedHeight: Dp,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

A basic two-rows Material Design top app bar.

Cmn

Functions

TwoRowsTopAppBar

@ExperimentalMaterial3ExpressiveApi
@Composable
fun TwoRowsTopAppBar(
    title: @Composable (expanded: Boolean) -> Unit,
    modifier: Modifier = Modifier,
    subtitle: (@Composable (expanded: Boolean) -> Unit)? = null,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    titleHorizontalAlignment: Alignment.Horizontal = Alignment.Start,
    collapsedHeight: Dp = Dp.Unspecified,
    expandedHeight: Dp = Dp.Unspecified,
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

A basic two-rows Material Design top app bar.

Top app bars display information and actions at the top of a screen.

Two rows top app bar
image

This two-rows top app bar has slots for titles and subtitles, navigation icon, and actions. In its default expanded state, the expanded title and subtitle are displayed in a second row under the navigation and actions.

By default, the two-rows top app bar will apply the MediumFlexibleTopAppBar text styles to the expanded and collapsed titles. You may override that by applying your own style to the Composition passed into those collapsed and expanded title slots.

A two-rows top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with scrolling content looks like:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TwoRowsTopAppBar
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp

val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TwoRowsTopAppBar(
            title = { expanded ->
                if (expanded) {
                    Text("Expanded TopAppBar", maxLines = 1, overflow = TextOverflow.Ellipsis)
                } else {
                    Text("Collapsed TopAppBar", maxLines = 1, overflow = TextOverflow.Ellipsis)
                }
            },
            subtitle = { expanded ->
                if (expanded) {
                    Text(
                        "Expanded Subtitle",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier.padding(bottom = 24.dp),
                    )
                } else {
                    Text("Collapsed Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis)
                }
            },
            collapsedHeight = 64.dp,
            expandedHeight = 156.dp,
            navigationIcon = {
                TooltipBox(
                    positionProvider =
                        TooltipDefaults.rememberTooltipPositionProvider(
                            TooltipAnchorPosition.Above
                        ),
                    tooltip = { PlainTooltip { Text("Menu") } },
                    state = rememberTooltipState(),
                ) {
                    IconButton(onClick = { /* doSomething() */ }) {
                        Icon(imageVector = Icons.Filled.Menu, contentDescription = "Menu")
                    }
                }
            },
            scrollBehavior = scrollBehavior,
        )
    },
    content = { innerPadding ->
        Column(
            Modifier.fillMaxWidth().padding(innerPadding).verticalScroll(rememberScrollState())
        ) {
            CompositionLocalProvider(
                LocalTextStyle provides MaterialTheme.typography.bodyLarge
            ) {
                Text(text = remember { LoremIpsum().values.first() })
            }
        }
    },
)
Parameters
title: @Composable (expanded: Boolean) -> Unit

a lambda for providing a title to be displayed in the top app bar in collapsed and expanded states. By default a small-app-bar TextStyle is applied to the Composition, and you may override it by wrapping your provided component with a composition local. Note that unlike the large or medium top app bars, the TwoRowsTopAppBar does not append bottom padding to the expanded title Composable by default. Padding should be applied directly to the provided expanded title, or to the subtitle that appears below it.

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

subtitle: (@Composable (expanded: Boolean) -> Unit)? = null

a lambda for providing an optional subtitle to be displayed in the top app bar in collapsed and expanded states.

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

titleHorizontalAlignment: Alignment.Horizontal = Alignment.Start

the horizontal alignment of the title and subtitle

collapsedHeight: Dp = Dp.Unspecified

the app bar's height in its collapsed state. Note that this value might be adjusted to support displaying larger fonts. In case the provided value is Dp.Unspecified or Dp.Infinity, the height will default to TopAppBarDefaults.MediumAppBarCollapsedHeight.

expandedHeight: Dp = Dp.Unspecified

this app bar's height in its expanded state. When a specified scrollBehavior causes the app bar to collapse or expand, this value will represent the total height that the app-bar will expand to. The expanded height is expected to be greater or equal to the collapsedHeight, and the function will throw an IllegalArgumentException otherwise. Note that this value might be adjusted to support displaying larger fonts. In case the provided value is Dp.Unspecified or Dp.Infinity, the height will default to TopAppBarDefaults.MediumFlexibleAppBarWithSubtitleExpandedHeight when an expandedSubtitle is provided, or to TopAppBarDefaults.MediumFlexibleAppBarWithoutSubtitleExpandedHeight when it's not.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.topAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

Throws
IllegalArgumentException

if the provided expandedHeight is smaller to the collapsedHeight