本文译自Exploring Jetpack Compose: SearchBar,原文链接:https://joebirch.co/android/exploring-the-searchbar-composable/ ,作者是Joe Birch。
在应用内搜索内容是一项常见功能,事实上,你可以在设备上的大多数应用程序中发现此功能。在 Android 上,我们看到的此功能的常见 UI 组件是浮动搜索栏,放置在屏幕的显眼位置。在某些情况下,这还会向用户提供搜索建议,以简化搜索过程。Jetpack Compose Material3 软件包提供了对提供此功能的 SearchBar 可组合项的访问,在这篇博文中,我们将学习如何在我们自己的应用中使用它。
SearchBar 可组合项允许我们显示一个浮动的搜索组件,该组件展开后会显示可选的推荐。如上所述,这是我们在许多应用中看到的常见模式,此可组合项提供了开箱即用的解决方案。SearchBar 可组合项提供了足够的自定义功能来控制组件的外观和感觉,同时使用基于插槽(slot)的方法让我们提供输入字段以供使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
@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 ,
)
该组件为我们处理了大部分内部工作——其中两个关键部分需要我们自己提供。
inputField – 这是表示内容输入的搜索字段的输入可组合项
content – 这是搜索栏展开时用于显示推荐的内容区域
除了这些字段之外,还有一组其他属性用于确定 SearchBar 的当前状态。例如,当搜索栏处于展开状态时,可组合项的内容将显示在输入字段下方。为了能够管理这一点,我们需要为可组合项提供一些参数,用于管理此状态。首先,expanded 参数用于描述 SearchBar 是否处于展开状态(这将决定是否显示内容区域),以及 onExpandedChange 参数,用于为实现提供展开状态的更新值(然后可用于反映我们自己的状态实现)。
1
2
3
4
5
6
7
8
9
var expanded by remember { mutableStateOf ( false ) }
SearchBar (
modifier = Modifier . fillMaxWidth (),
expanded = expanded ,
onExpandedChange = {
expanded = it
}
)
除了管理这种展开状态外,我们还需要提供用于 SearchBar 输入区域的 inputField。除了遵循可组合项的基于插槽的方法之外,这还允许可组合项遵循状态提升的概念,使我们能够完全管理 SearchBar 输入字段的状态概念。
1
2
3
4
5
6
7
8
9
10
11
12
13
var expanded by remember { mutableStateOf ( false ) }
var query by remember { mutableStateOf < String ?>( null ) }
SearchBar (
modifier = Modifier . fillMaxWidth (),
expanded = expanded ,
onExpandedChange = {
expanded = it
},
inputField = {
// ...
}
)
为了简化此操作,SearchBarDefaults 类为我们提供了对 InputField 可组合项的访问 - 这使我们能够访问专门为 SearchBar 实现的可组合项。不需要使用此特定可组合项,但它是专门为基于搜索的输入字段提供的便利可组合项。此可组合项采用一些关键参数,用于将其配置为在 SearchBar 中使用:
expanded 和 onExpandedChange - 用于管理字段的展开状态
query 和 onQueryChange - 用于管理字段中显示的查询的状态
除了这些核心属性外,你还会注意到对标准字段参数(如占位符、leadingIcon 和 trailingIcon)的支持。除了用于提供信息之外,我们还可以在下面的示例中看到我如何使用 trailingIcon 允许 SearchBar 在单击取消按钮时恢复到折叠状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SearchBarDefaults . InputField (
onSearch = { expanded = false },
expanded = expanded ,
onExpandedChange = { expanded = it },
placeholder = { Text ( "What are you looking for?" ) },
leadingIcon = { Icon ( Icons . Default . Search , contentDescription = null ) },
trailingIcon = {
if ( expanded ) {
IconButton ( onClick = {
expanded = false
}) {
Icon ( Icons . Default . Close , contentDescription = null )
}
}
},
query = query ?: "" ,
onQueryChange = {
query = it
}
)
然后可以将此 InputField 可组合项的实现插入到 SearchBar 可组合项的 inputField 参数中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var expanded by remember { mutableStateOf ( false ) }
var query by remember { mutableStateOf < String ?>( null ) }
SearchBar (
modifier = Modifier . fillMaxWidth (),
expanded = expanded ,
onExpandedChange = {
expanded = it
},
inputField = {
SearchBarDefaults . InputField (
onSearch = { expanded = false },
expanded = expanded ,
onExpandedChange = { expanded = it },
placeholder = { Text ( "What are you looking for?" ) },
leadingIcon = { Icon ( Icons . Default . Search , contentDescription = null ) },
trailingIcon = {
if ( expanded ) {
IconButton ( onClick = {
expanded = false
}) {
Icon ( Icons . Default . Close , contentDescription = null )
}
}
},
query = query ?: "" ,
onQueryChange = {
query = it
}
)
}
)
此时,我们将能够组合 SearchBar 并看到在我们的 UI 中显示的浮动组件。
此时我们剩下要实现的就是 SearchBar 的内容,这是 SearchBar 处于展开状态时显示的内容。此参数利用了 ColumnScope,因此此处提供的任何可组合项都将垂直堆叠。此内容区域的预期形式是用户可以选择的推荐列表,因此我们将继续编写几个 ListItem 可组合项,每个可组合项都用于向用户显示搜索推荐。当点击其中任何一项时,查询将更新为选定值,并且 SearchBar 的展开状态将重置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var expanded by remember { mutableStateOf ( false ) }
var query by remember { mutableStateOf < String ?>( null ) }
SearchBar (
...
) {
listOf ( "Result 1" , "Result 2" , "Result 3" , "Result 4" ). forEach { text ->
ListItem (
headlineContent = { Text ( text ) },
colors = ListItemDefaults . colors ( containerColor = Color . Transparent ),
modifier = Modifier . clickable {
query = text
expanded = false
}. fillMaxWidth (). padding ( horizontal = 16. dp , vertical = 8. dp )
)
}
}
有了此功能,我们现在就能够看到在浮动搜索栏下方显示的推荐。
有了上述内容,我们就可以实现一个浮动搜索栏,向用户显示搜索建议。使用 Material3 SearchBar 可组合项,实现在这两种不同状态之间转换的可组合项非常容易。也许你已经在应用中使用了 SearchBar,或者一直在寻找类似的功能,但无论如何,我期待看到更多应用通过 Jetpack Compose 中更广泛的组件支持来节省时间!