AppBarRow

Functions summary

Unit
@Composable
AppBarRow(
    modifier: Modifier,
    overflowIndicator: @Composable (AppBarMenuState) -> Unit,
    maxItemCount: Int,
    content: AppBarRowScope.() -> Unit
)

An AppBarRow arranges its children in a horizontal sequence, and if any children overflow the constraints, an overflow indicator is displayed.

Cmn

Functions

@Composable
fun AppBarRow(
    modifier: Modifier = Modifier,
    overflowIndicator: @Composable (AppBarMenuState) -> Unit = { menuState -> AppBarOverflowIndicator(menuState) },
    maxItemCount: Int = Int.MAX_VALUE,
    content: AppBarRowScope.() -> Unit
): Unit

An AppBarRow arranges its children in a horizontal sequence, and if any children overflow the constraints, an overflow indicator is displayed.

This composable lays out its children from left to right in LTR layouts and from right to left in RTL layouts. If the children's combined width exceeds the available width, overflowIndicator is displayed at the end of the row, replacing the content that otherwise cannot fit. The items are constructed through a DSL in AppBarRowScope. Each item provides a way to render itself in the row layout, and an alternative way, to render inside of a dropdown menu, when there is overflow.

A sample with an TopAppBar, that varies the number of actions shown.

import androidx.compose.foundation.layout.Arrangement
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.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Attachment
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Snooze
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.outlined.MarkEmailUnread
import androidx.compose.material.icons.outlined.Star
import androidx.compose.material3.AppBarRow
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
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.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.window.core.layout.WindowSizeClass

val sizeClass = currentWindowAdaptiveInfo().windowSizeClass
// Material guidelines state 3 items max in compact, and 5 items max elsewhere.
// To test this, try a resizable emulator, or a phone in landscape and portrait orientation.
val maxItemCount =
    if (sizeClass.minWidthDp >= WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) {
        5
    } else {
        3
    }
val icons =
    listOf(
        Icons.Filled.Attachment,
        Icons.Filled.Edit,
        Icons.Outlined.Star,
        Icons.Filled.Snooze,
        Icons.Outlined.MarkEmailUnread,
    )
val items = listOf("Attachment", "Edit", "Star", "Snooze", "Mark unread")

Scaffold(
    topBar = {
        TopAppBar(
            title = {
                Text("Simple TopAppBar", maxLines = 1, overflow = TextOverflow.Ellipsis)
            },
            navigationIcon = {
                TooltipBox(
                    positionProvider =
                        TooltipDefaults.rememberTooltipPositionProvider(
                            TooltipAnchorPosition.Above
                        ),
                    tooltip = { PlainTooltip { Text("Menu") } },
                    state = rememberTooltipState(),
                ) {
                    IconButton(onClick = { /* doSomething() */ }) {
                        Icon(imageVector = Icons.Filled.Menu, contentDescription = "Menu")
                    }
                }
            },
            actions = {
                AppBarRow(
                    maxItemCount = maxItemCount,
                    overflowIndicator = {
                        TooltipBox(
                            positionProvider =
                                TooltipDefaults.rememberTooltipPositionProvider(
                                    TooltipAnchorPosition.Above
                                ),
                            tooltip = { PlainTooltip { Text("Overflow") } },
                            state = rememberTooltipState(),
                        ) {
                            IconButton(onClick = { it.show() }) {
                                Icon(
                                    imageVector = Icons.Filled.MoreVert,
                                    contentDescription = "Overflow",
                                )
                            }
                        }
                    },
                ) {
                    items.forEachIndexed { index, item ->
                        clickableItem(
                            onClick = {},
                            icon = {
                                Icon(imageVector = icons[index], contentDescription = item)
                            },
                            label = item,
                        )
                    }
                }
            },
        )
    },
    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),
                )
            }
        }
    },
)
Parameters
modifier: Modifier = Modifier

The modifier to be applied to the row.

overflowIndicator: @Composable (AppBarMenuState) -> Unit = { menuState -> AppBarOverflowIndicator(menuState) }

A composable that is displayed at the end of the row when the content overflows. It receives an AppBarMenuState instance.

maxItemCount: Int = Int.MAX_VALUE

the max amount of items that should render in the row, before starting to use the overflow menu. Consider that using large items or small constraints, will reduce the effective maximum. Note: If the number of items supplied is bigger than max, at most max - 1 items will render, since the last one will be dedicated to the overflow composable.

content: AppBarRowScope.() -> Unit

The content to be arranged in the row, defined using a dsl with AppBarRowScope.