Search bar

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.

Figure 1. A basic search bar (1) and a search bar with a suggestion (2).

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.

This snippet shows a basic implementation of SearchBar with suggestions:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
funSimpleSearchBar(
textFieldState:TextFieldState,
onSearch:(String)->Unit,
searchResults:List<String>,
modifier:Modifier=Modifier
){
// Controls expansion state of the search bar
varexpandedbyrememberSaveable{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

  • rememberSaveable ensures that whether the search bar is expanded or collapsed is preserved across configuration changes. It writes the remembered value into the hosting Activity's savedInstanceState bundle before the Activity is destroyed during a configuration change.
  • The semantics modifier controls the TalkBack traversal order.
    • isTraversalGroup is set for Box to group all its child composables.
    • traversalIndex is 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.0 and 1.0 on each peer.
  • The SearchBar contains an inputField for user input and a Column to display search suggestions.
    • SearchBarDefaults.InputField creates the input field and handles changes to the user query.
    • onQueryChange handles the text input and updates the state whenever the text in the input field changes.
    • The expanded state controls the visibility of the suggestion list.
  • searchResults.forEach { result -> ... } iterates through the searchResults list and creates a ListItem for each result.
    • When a ListItem is clicked, it updates the textFieldState, collapses the search bar, and fills the textField with the selected search result.

Result

Figure 2. A search bar with suggestions displayed.

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
funCustomizableSearchBar(
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
varexpandedbyrememberSaveable{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->
valresultText=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 onQueryChange lambda function is called whenever the user types or deletes text in the search bar.
  • SearchBarDefaults.InputField contains 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 onSearch lambda and collapses the search bar when the search is submitted.
  • A LazyColumn handles a potentially large number of search results efficiently. It iterates through the searchResults list and displays each result as a ListItem.
  • Each ListItem composable shows the item text, text showing additional information, and a star icon as the item's leadingContent. In this example, an option to favorite the item is presented.
  • For the filtering logic, see CustomizableSearchBarExample in the full source code on GitHub.

Result

Figure 3. A search bar with relevant suggestions displayed.

Additional resources

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2025年12月29日 UTC.