This guide explains how to create a dynamic top app bar in Compose that changes its options when items are selected from the list. You can modify the top app bar's title and actions based on the selection state.
Implement dynamic top app bar behavior
This code defines a composable function for the top app bar that changes based on item selection:
@Composable fun AppBarSelectionActions( selectedItems: Set<Int>, modifier: Modifier = Modifier, ) { val hasSelection = selectedItems.isNotEmpty() val topBarText = if (hasSelection) { "Selected ${selectedItems.size} items" } else { "List of items" } TopAppBar( title = { Text(topBarText) }, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.primaryContainer, titleContentColor = MaterialTheme.colorScheme.primary, ), actions = { if (hasSelection) { IconButton(onClick = { /* click action */ }) { Icon( imageVector = Icons.Filled.Share, contentDescription = "Share items" ) } } }, ) }
Key points about the code
AppBarSelectionActions
accepts aSet
of selected item indices.- The
topBarText
changes depending on whether any items are selected.- When items are selected, text describing the number of items selected
appears in the
TopAppBar
. - If no items are selected the
topBarText
is "List of items".
- When items are selected, text describing the number of items selected
appears in the
- The
actions
block defines the actions displayed in the top app bar. IfhasSelection
is true, a share icon appears after the text. - The
onClick
lambda of theIconButton
handles the share action when the icon is clicked.
Result
Integrate selectable list into dynamic top app bar
This example demonstrates how to add a selectable list to a dynamic top app bar:
@Composable private fun AppBarMultiSelectionExample( modifier: Modifier = Modifier, ) { val listItems by remember { mutableStateOf(listOf(1, 2, 3, 4, 5, 6)) } var selectedItems by rememberSaveable { mutableStateOf(setOf<Int>()) } Scaffold( topBar = { AppBarSelectionActions(selectedItems) } ) { innerPadding -> LazyColumn(contentPadding = innerPadding) { itemsIndexed(listItems) { _, index -> val isItemSelected = selectedItems.contains(index) ListItemSelectable( selected = isItemSelected, Modifier .combinedClickable( interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = { /* click action */ }, onLongClick = { if (isItemSelected) selectedItems -= index else selectedItems += index } ) ) } } } }
Key points about the code
- The top bar updates based on how many list items are selected.
selectedItems
holds the set of selected item indices.AppBarMultiSelectionExample
uses aScaffold
to structure the screen.topBar = { AppBarSelectionActions(selectedItems)
} sets theAppBarSelectionActions
composable as the top app bar.AppBarSelectionActions
receives theselectedItems
state.
LazyColumn
displays the items in a vertical list, rendering only the items visible on the screen.ListItemSelectable
represents a selectable list item.combinedClickable
allows both click and long-click handling for item selection. A click performs an action, while long-clicking an item toggles its selection state.