Use a search bar to implement search functionality. A search bar is a persistent search field that lets users enter a keyword or phrase to display relevant results within your app, and is recommended when search is the primary focus of your app.
 
  API surface
Use the SearchBar composable to implement search bars. Key parameters for
this composable include the following:
- inputField: Defines the input field of the search bar. It typically utilizes- SearchBarDefaults.InputField, which allows customization of:- query: The query text to be shown in the input field..
- onQueryChange: Lambda to handle changes in the query string.
 
- expanded: A boolean indicating whether the search bar is expanded to show suggestions or filtered results.
- onExpandedChange: Lambda to handle changes in the dropdown's expanded state.
- content: The content of this search bar to display search results below the- inputField.
Search bar with suggestions
This snippet shows a basic implementation of SearchBar with suggestions:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun SimpleSearchBar( textFieldState: TextFieldState, onSearch: (String) -> Unit, searchResults: List<String>, modifier: Modifier = Modifier ) { // Controls expansion state of the search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { SearchBarDefaults.InputField( query = textFieldState.text.toString(), onQueryChange = { textFieldState.edit { replace(0, length, it) } }, onSearch = { onSearch(textFieldState.text.toString()) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = { Text("Search") } ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Display search results in a scrollable column Column(Modifier.verticalScroll(rememberScrollState())) { searchResults.forEach { result -> ListItem( headlineContent = { Text(result) }, modifier = Modifier .clickable { textFieldState.edit { replace(0, length, result) } expanded = false } .fillMaxWidth() ) } } } } }
Key points about the code
- rememberSaveableensures that whether the search bar is expanded or collapsed is preserved across configuration changes. It writes the remembered value into the hosting Activity's- savedInstanceStatebundle before the Activity is destroyed during a configuration change.
- The semanticsmodifier controls the TalkBack traversal order.- isTraversalGroupis set for- Boxto group all its child composables.
- traversalIndexis set to specify the order in which TalkBack reads accessibility information from each group peer. TalkBack reads accessibility information on a peer with a negative value, such as- -1, before a peer with a positive value, such as- 1. Because the value is a float, you can specify a custom order of many peers by setting values in between- -1.0and- 1.0on each peer.
 
- The SearchBarcontains aninputFieldfor user input and aColumnto display search suggestions.- SearchBarDefaults.InputFieldcreates the input field and handles changes to the user query.
- onQueryChangehandles the text input and updates the state whenever the text in the input field changes.
- The expandedstate controls the visibility of the suggestion list.
 
- searchResults.forEach { result -> … }iterates through the- searchResultslist and creates a- ListItemfor each result.- When a ListItemis clicked, it updates thetextFieldState, collapses the search bar, and fills thetextFieldwith the selected search result.
 
- When a 
Result
 
  Search bar with filtered list
This example shows a SearchBar that filters a list based on the user's search
query:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, modifier: Modifier = Modifier, // Customization options placeholder: @Composable () -> Unit = { Text("Search") }, leadingIcon: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIcon: @Composable (() -> Unit)? = null, supportingContent: (@Composable (String) -> Unit)? = null, leadingContent: (@Composable () -> Unit)? = null, ) { // Track expanded state of search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { // Customizable input field implementation SearchBarDefaults.InputField( query = query, onQueryChange = onQueryChange, onSearch = { onSearch(query) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = placeholder, leadingIcon = leadingIcon, trailingIcon = trailingIcon ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Show search results in a lazy column for better performance LazyColumn { items(count = searchResults.size) { index -> val resultText = searchResults[index] ListItem( headlineContent = { Text(resultText) }, supportingContent = supportingContent?.let { { it(resultText) } }, leadingContent = leadingContent, colors = ListItemDefaults.colors(containerColor = Color.Transparent), modifier = Modifier .clickable { onResultClick(resultText) expanded = false } .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 4.dp) ) } } } } }
Key points about the code
- The onQueryChangelambda function is called whenever the user types or deletes text in the search bar.
- SearchBarDefaults.InputFieldcontains a- leadingIcon, which adds a search icon to the beginning of the input field, and a- trailingIcon, which adds a "more options" icon to the end of the input field. Here, you can provide sorting and filtering options to the user.
- onSearch = { … }calls the- onSearchlambda and collapses the search bar when the search is submitted.
- A LazyColumnhandles a potentially large number of search results efficiently. It iterates through thesearchResultslist and displays each result as aListItem.
- Each ListItemcomposable shows the item text, text showing additional information, and a star icon as the item'sleadingContent. In this example, an option to favorite the item is presented.
- For the filtering logic, see CustomizableSearchBarExamplein the full source code on GitHub.
Result
 
  Additional resources
- Material Design: Search bar
