SearchBar
Android
Component in Material 3 Compose
A search bar represents a floating search field that allows users to enter a keyword or phrase and get relevant information. It can be used as a way to navigate through an app via search queries.
A search bar expands into a search "view" and can be used to display dynamic suggestions or search results.
Last updated:
Installation
dependencies {
implementation("androidx.compose.material3:material3:1.4.0-alpha02")
}
Overloads
@ExperimentalMaterial3Api
@Composable
fun SearchBar(
inputField: @Composable () -> Unit,
expanded: Boolean,
onExpandedChange: (Boolean) -> Unit,
modifier: Modifier = Modifier,
shape: Shape = SearchBarDefaults.inputFieldShape,
colors: SearchBarColors = SearchBarDefaults.colors(),
tonalElevation: Dp = SearchBarDefaults.TonalElevation,
shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
content: @Composable ColumnScope.() -> Unit,
)
Parameters
name | description |
---|---|
inputField | the input field of this search bar that allows entering a query, typically a [SearchBarDefaults.InputField]. |
expanded | whether this search bar is expanded and showing search results. |
onExpandedChange | the callback to be invoked when this search bar's expanded state is changed. |
modifier | the [Modifier] to be applied to this search bar. |
shape | the shape of this search bar when it is not [expanded]. When [expanded], the shape will always be [SearchBarDefaults.fullScreenShape]. |
colors | [SearchBarColors] that will be used to resolve the colors used for this search bar in different states. See [SearchBarDefaults.colors]. |
tonalElevation | when [SearchBarColors.containerColor] is [ColorScheme.surface], a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: [Surface]. |
shadowElevation | the elevation for the shadow below this search bar |
windowInsets | the window insets that this search bar will respect |
content | the content of this search bar to display search results below the [inputField]. |
@Suppress("DEPRECATION")
@Deprecated(
message = "Use overload which takes inputField as a parameter",
replaceWith =
ReplaceWith(
"SearchBar(\n" +
" inputField = {\n" +
" SearchBarDefaults.InputField(\n" +
" query = query,\n" +
" onQueryChange = onQueryChange,\n" +
" onSearch = onSearch,\n" +
" expanded = active,\n" +
" onExpandedChange = onActiveChange,\n" +
" enabled = enabled,\n" +
" placeholder = placeholder,\n" +
" leadingIcon = leadingIcon,\n" +
" trailingIcon = trailingIcon,\n" +
" colors = colors.inputFieldColors,\n" +
" interactionSource = interactionSource,\n" +
" )\n" +
" },\n" +
" expanded = active,\n" +
" onExpandedChange = onActiveChange,\n" +
" modifier = modifier,\n" +
" shape = shape,\n" +
" colors = colors,\n" +
" tonalElevation = tonalElevation,\n" +
" shadowElevation = shadowElevation,\n" +
" windowInsets = windowInsets,\n" +
" content = content,\n" +
")"
),
)
@ExperimentalMaterial3Api
@Composable
fun SearchBar(
query: String,
onQueryChange: (String) -> Unit,
onSearch: (String) -> Unit,
active: Boolean,
onActiveChange: (Boolean) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
shape: Shape = SearchBarDefaults.inputFieldShape,
colors: SearchBarColors = SearchBarDefaults.colors(),
tonalElevation: Dp = SearchBarDefaults.TonalElevation,
shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
interactionSource: MutableInteractionSource? = null,
content: @Composable ColumnScope.() -> Unit,
)
Code Example
SearchBarSample
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun SearchBarSample() {
val textFieldState = rememberTextFieldState()
var expanded by rememberSaveable { mutableStateOf(false) }
Box(Modifier.fillMaxSize().semantics { isTraversalGroup = true }) {
SearchBar(
modifier = Modifier.align(Alignment.TopCenter).semantics { traversalIndex = 0f },
inputField = {
SearchBarDefaults.InputField(
state = textFieldState,
onSearch = { expanded = false },
expanded = expanded,
onExpandedChange = { expanded = it },
placeholder = { Text("Hinted search text") },
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
trailingIcon = { Icon(Icons.Default.MoreVert, contentDescription = null) },
)
},
expanded = expanded,
onExpandedChange = { expanded = it },
) {
Column(Modifier.verticalScroll(rememberScrollState())) {
repeat(4) { idx ->
val resultText = "Suggestion $idx"
ListItem(
headlineContent = { Text(resultText) },
supportingContent = { Text("Additional info") },
leadingContent = { Icon(Icons.Filled.Star, contentDescription = null) },
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
modifier =
Modifier.clickable {
textFieldState.setTextAndPlaceCursorAtEnd(resultText)
expanded = false
}
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 4.dp)
)
}
}
}
LazyColumn(
contentPadding = PaddingValues(start = 16.dp, top = 72.dp, end = 16.dp, bottom = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.semantics { traversalIndex = 1f },
) {
val list = List(100) { "Text $it" }
items(count = list.size) {
Text(
text = list[it],
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
)
}
}
}
}