使用搜索栏实现搜索功能。搜索栏是一种永久性搜索字段,可让用户输入关键字或字词,以便在应用中显示相关结果。如果搜索是应用的主要功能,则建议使用搜索栏。

API Surface
使用 SearchBar
可组合项实现搜索栏。此可组合项的关键参数包括:
inputField
:定义搜索栏的输入字段。它通常使用SearchBarDefaults.InputField
,可自定义以下内容:query
:要显示在输入字段中的查询文本。onQueryChange
:用于处理查询字符串更改的 Lambda。
expanded
:一个布尔值,指示搜索栏是否已展开即可显示建议或过滤后的结果。onExpandedChange
:用于处理下拉菜单展开状态变化的 Lambda。content
:此搜索栏的内容,用于在inputField
下方显示搜索结果。
显示搜索建议的搜索栏
以下代码段展示了包含建议的基本 SearchBar
实现:
@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() ) } } } } }
代码要点
rememberSaveable
可确保搜索栏是展开还是收起的状态在配置更改后保持不变。它会在配置更改期间销毁 activity 之前,将记住的值写入托管 activity 的savedInstanceState
bundle。semantics
修饰符用于控制 TalkBack 遍历顺序。- 为
Box
设置isTraversalGroup
以对其所有子可组合项进行分组。 traversalIndex
用于指定 TalkBack 从每个群组对等方读取无障碍信息的顺序。TalkBack 会先读取值为负(例如-1
)的对等项的无障碍信息,然后再读取值为正(例如1
)的对等项的无障碍信息。由于该值是浮点值,因此您可以通过为每个对等点设置介于-1.0
和1.0
之间的值,指定多个对等点的自定义顺序。
- 为
SearchBar
包含用于用户输入的inputField
,以及用于显示搜索建议的Column
。SearchBarDefaults.InputField
会创建输入字段并处理用户查询的更改。- 每当输入字段中的文本发生变化时,
onQueryChange
都会处理文本输入并更新状态。 The expanded
状态用于控制建议列表的可见性。
searchResults.forEach { result -> … }
会遍历searchResults
列表,并为每个结果创建一个ListItem
。- 点击
ListItem
后,系统会更新textFieldState
、收起搜索栏,并使用所选搜索结果填充textField
。
- 点击
结果

带有过滤列表的搜索栏
以下示例展示了一个 SearchBar
,用于根据用户的搜索查询过滤列表:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, // 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, modifier: Modifier = Modifier ) { // 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) ) } } } } }
代码要点
- 每当用户在搜索栏中输入或删除文本时,系统都会调用
onQueryChange
lambda 函数。 SearchBarDefaults.InputField
包含一个leadingIcon
,用于向输入字段的开头添加搜索图标,以及一个trailingIcon
,用于向输入字段的末尾添加“更多选项”图标。在这里,您可以向用户提供排序和过滤选项。onSearch = { … }
会在提交搜索时调用onSearch
lambda 并收起搜索栏。LazyColumn
可高效处理可能数量众多的搜索结果。它会遍历searchResults
列表,并将每个结果显示为ListItem
。- 每个
ListItem
可组合项都会显示商品文本、显示其他信息的文本,以及作为商品leadingContent
的星形图标。在此示例中,系统会显示用于将内容收藏为“收藏夹”的选项。 - 如需了解过滤逻辑,请参阅 GitHub 上的完整源代码中的
CustomizableSearchBarExample
。
结果

其他资源
- Material Design:搜索栏