---
title: "FlexibleBottomAppBar"
description: "A flexible bottom app bar displays navigation and key actions at the bottom of small screens."
type: "component"
---

<div class='type'>Composable Component</div>



A flexible bottom app bar displays navigation and key actions at the bottom of small screens.

<a id='references'></a>

<div class='sourceset sourceset-common'>Common</div>


```kotlin
@ExperimentalMaterial3ExpressiveApi
@Composable
fun FlexibleBottomAppBar(
    modifier: Modifier = Modifier,
    containerColor: Color = BottomAppBarDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    contentPadding: PaddingValues = BottomAppBarDefaults.FlexibleContentPadding,
    horizontalArrangement: Arrangement.Horizontal =
        BottomAppBarDefaults.FlexibleHorizontalArrangement,
    expandedHeight: Dp = BottomAppBarDefaults.FlexibleBottomAppBarHeight,
    windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets,
    scrollBehavior: BottomAppBarScrollBehavior? = null,
    content: @Composable RowScope.() -> Unit,
)
```


#### Parameters

| | |
| --- | --- |
| modifier | the `Modifier` to be applied to this BottomAppBar |
| containerColor | the color used for the background of this BottomAppBar. Use `Color.Transparent` to have no color. |
| contentColor | the preferred color for content inside this BottomAppBar. Defaults to either the matching content color for `containerColor`, or to the current `LocalContentColor` if `containerColor` is not a color from the theme. |
| contentPadding | the padding applied to the content of this BottomAppBar |
| horizontalArrangement | the horizontal arrangement of the content inside this BottomAppBar |
| expandedHeight | the maximum height this bottom bar can reach when fully expanded. If a `scrollBehavior` is provided, the bar might collapse or expand based on scrolling. In that case, this value sets the upper limit for the bar's height during expansion. This `Dp` value must be specified, finite, and greater than zero; otherwise, `BottomAppBarDefaults.FlexibleBottomAppBarHeight` will be used as a default. In case the `scrollBehavior` is `null`, this value will simply be the fixed height of the bottom bar. |
| windowInsets | a window insets that app bar will respect. |
| scrollBehavior | a `BottomAppBarScrollBehavior` which holds various offset values that will be applied by this bottom app bar to set up its height. A scroll behavior is designed to work in conjunction with a scrolled content to change the bottom app bar appearance as the content scrolls. Note that the bottom app bar will not react to scrolling in case a touch exploration service (e.g., TalkBack) is active. See `BottomAppBarScrollBehavior.nestedScrollConnection`. |
| content | the content of this BottomAppBar. The default layout here is a `Row`, so content inside will be placed horizontally. |






## Code Examples
### BottomAppBarWithOverflow
```kotlin
/** A sample for a [FlexibleBottomAppBar] with an overflow behavior when the content doesn't fit. */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun BottomAppBarWithOverflow() {
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
            Icons.Filled.Favorite,
        )
    val items = listOf("Back", "Forward", "Add", "Check", "Edit", "Favorite")
    FlexibleBottomAppBar(
        contentPadding = PaddingValues(horizontal = 96.dp),
        horizontalArrangement = BottomAppBarDefaults.FlexibleFixedHorizontalArrangement,
    ) {
        AppBarRow(
            overflowIndicator = { menuState ->
                TooltipBox(
                    positionProvider =
                        TooltipDefaults.rememberTooltipPositionProvider(
                            TooltipAnchorPosition.Above
                        ),
                    tooltip = { PlainTooltip { Text("Overflow") } },
                    state = rememberTooltipState(),
                ) {
                    IconButton(
                        onClick = {
                            if (menuState.isShowing) {
                                menuState.dismiss()
                            } else {
                                menuState.show()
                            }
                        }
                    ) {
                        Icon(imageVector = Icons.Filled.MoreVert, contentDescription = "Overflow")
                    }
                }
            }
        ) {
            items.forEachIndexed { index, item ->
                clickableItem(
                    onClick = { /* doSomething() */ },
                    icon = { Icon(icons[index], contentDescription = item) },
                    label = item,
                )
            }
        }
    }
}
```
### ExitAlwaysBottomAppBarFixed
```kotlin
/**
 * A sample for a [FlexibleBottomAppBar] that collapses when the content is scrolled up, and appears
 * when the content scrolled down. The content arrangement is fixed.
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ExitAlwaysBottomAppBarFixed() {
    val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
        )
    val buttons = listOf("Back", "Forward", "Add", "Check", "Edit")
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        bottomBar = {
            FlexibleBottomAppBar(
                horizontalArrangement = BottomAppBarDefaults.FlexibleFixedHorizontalArrangement,
                scrollBehavior = scrollBehavior,
                content = {
                    buttons.forEachIndexed { index, button ->
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text(button) } },
                            state = rememberTooltipState(),
                        ) {
                            if (index == 2) {
                                FilledIconButton(
                                    modifier = Modifier.width(56.dp),
                                    onClick = { /* doSomething() */ },
                                ) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            } else {
                                IconButton(onClick = { /* doSomething() */ }) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            }
                        }
                    }
                },
            )
        },
        content = { innerPadding ->
            LazyColumn(
                contentPadding = innerPadding,
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                val list = (0..75).map { it.toString() }
                items(count = list.size) {
                    Text(
                        text = list[it],
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                    )
                }
            }
        },
    )
}
```
### ExitAlwaysBottomAppBarFixedVibrant
```kotlin
/**
 * A sample for a vibrant [FlexibleBottomAppBar] that collapses when the content is scrolled up, and
 * appears when the content scrolled down. The content arrangement is fixed.
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ExitAlwaysBottomAppBarFixedVibrant() {
    val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
        )
    val buttons = listOf("Back", "Forward", "Add", "Check", "Edit")
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        bottomBar = {
            FlexibleBottomAppBar(
                horizontalArrangement = BottomAppBarDefaults.FlexibleFixedHorizontalArrangement,
                scrollBehavior = scrollBehavior,
                containerColor =
                    MaterialTheme.colorScheme.primaryContainer, // TODO(b/356885344): tokens
                content = {
                    buttons.forEachIndexed { index, button ->
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text(button) } },
                            state = rememberTooltipState(),
                        ) {
                            if (index == 2) {
                                FilledIconButton(
                                    modifier = Modifier.width(56.dp),
                                    onClick = { /* doSomething() */ },
                                ) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            } else {
                                IconButton(onClick = { /* doSomething() */ }) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            }
                        }
                    }
                },
            )
        },
        content = { innerPadding ->
            LazyColumn(
                contentPadding = innerPadding,
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                val list = (0..75).map { it.toString() }
                items(count = list.size) {
                    Text(
                        text = list[it],
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                    )
                }
            }
        },
    )
}
```
### ExitAlwaysBottomAppBarSpacedAround
```kotlin
/**
 * A sample for a [FlexibleBottomAppBar] that collapses when the content is scrolled up, and appears
 * when the content scrolled down. The content is spaced around.
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ExitAlwaysBottomAppBarSpacedAround() {
    val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
        )
    val buttons = listOf("Back", "Forward", "Add", "Check", "Edit")
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        bottomBar = {
            FlexibleBottomAppBar(
                horizontalArrangement = Arrangement.SpaceAround,
                contentPadding = PaddingValues(horizontal = 0.dp),
                scrollBehavior = scrollBehavior,
                content = {
                    buttons.forEachIndexed { index, button ->
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text(button) } },
                            state = rememberTooltipState(),
                        ) {
                            if (index == 2) {
                                FilledIconButton(
                                    modifier = Modifier.width(56.dp),
                                    onClick = { /* doSomething() */ },
                                ) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            } else {
                                IconButton(onClick = { /* doSomething() */ }) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            }
                        }
                    }
                },
            )
        },
        content = { innerPadding ->
            LazyColumn(
                contentPadding = innerPadding,
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                val list = (0..75).map { it.toString() }
                items(count = list.size) {
                    Text(
                        text = list[it],
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                    )
                }
            }
        },
    )
}
```
### ExitAlwaysBottomAppBarSpacedBetween
```kotlin
/**
 * A sample for a [FlexibleBottomAppBar] that collapses when the content is scrolled up, and appears
 * when the content scrolled down. The content is spaced between.
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ExitAlwaysBottomAppBarSpacedBetween() {
    val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
        )
    val buttons = listOf("Back", "Forward", "Add", "Check", "Edit")
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        bottomBar = {
            FlexibleBottomAppBar(
                horizontalArrangement = Arrangement.SpaceBetween,
                scrollBehavior = scrollBehavior,
                content = {
                    buttons.forEachIndexed { index, button ->
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text(button) } },
                            state = rememberTooltipState(),
                        ) {
                            if (index == 2) {
                                FilledIconButton(
                                    modifier = Modifier.width(56.dp),
                                    onClick = { /* doSomething() */ },
                                ) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            } else {
                                IconButton(onClick = { /* doSomething() */ }) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            }
                        }
                    }
                },
            )
        },
        content = { innerPadding ->
            LazyColumn(
                contentPadding = innerPadding,
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                val list = (0..75).map { it.toString() }
                items(count = list.size) {
                    Text(
                        text = list[it],
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                    )
                }
            }
        },
    )
}
```
### ExitAlwaysBottomAppBarSpacedEvenly
```kotlin
/**
 * A sample for a [FlexibleBottomAppBar] that collapses when the content is scrolled up, and appears
 * when the content scrolled down. The content is spaced evenly.
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ExitAlwaysBottomAppBarSpacedEvenly() {
    val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
    val icons =
        listOf(
            Icons.AutoMirrored.Filled.ArrowBack,
            Icons.AutoMirrored.Filled.ArrowForward,
            Icons.Filled.Add,
            Icons.Filled.Check,
            Icons.Filled.Edit,
        )
    val buttons = listOf("Back", "Forward", "Add", "Check", "Edit")
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        bottomBar = {
            FlexibleBottomAppBar(
                horizontalArrangement = Arrangement.SpaceEvenly,
                contentPadding = PaddingValues(horizontal = 0.dp),
                scrollBehavior = scrollBehavior,
                content = {
                    buttons.forEachIndexed { index, button ->
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text(button) } },
                            state = rememberTooltipState(),
                        ) {
                            if (index == 2) {
                                FilledIconButton(
                                    modifier = Modifier.width(56.dp),
                                    onClick = { /* doSomething() */ },
                                ) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            } else {
                                IconButton(onClick = { /* doSomething() */ }) {
                                    Icon(icons[index], contentDescription = button)
                                }
                            }
                        }
                    }
                },
            )
        },
        content = { innerPadding ->
            LazyColumn(
                contentPadding = innerPadding,
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                val list = (0..75).map { it.toString() }
                items(count = list.size) {
                    Text(
                        text = list[it],
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                    )
                }
            }
        },
    )
}
```

