使用搜索栏实现搜索功能。搜索栏是一个持久的搜索字段,允许用户输入关键字或短语,以在应用内显示相关结果,当搜索是应用的主要焦点时,建议使用搜索栏。

API 外观
使用 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 的savedInstanceState
捆绑包中,然后再在配置更改期间销毁 Activity。- 的
semantics
修饰符控制 TalkBack 的遍历顺序。- 为
Box
设置isTraversalGroup
以对其所有子可组合项进行分组。 - 设置
traversalIndex
可指定 TalkBack 从每个组对等方读取无障碍信息时的顺序。TalkBack 会先读取具有负值(例如-1
)的对等方的无障碍信息,然后再读取具有正值(例如1
)的对等方的无障碍信息。由于该值为浮点数,因此您可以通过为每个对等方设置介于-1.0
和1.0
之间的值来指定许多对等方的自定义顺序。
- 为
SearchBar
包含一个用于用户输入的inputField
和一个用于显示搜索建议的Column
。SearchBarDefaults.InputField
会创建输入字段并处理用户查询的更改。onQueryChange
用于处理文本输入,并在输入字段中的文本发生更改时更新状态。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:搜索栏