实战:探索Jetpack Compose中的SearchBar

本文译自Exploring Jetpack Compose: SearchBar,原文链接:joebirch.co/android/exp...,作者是Joe Birch。

在应用内搜索内容是一项常见功能,事实上,您可以在设备上的大多数应用程序中发现此功能。在 Android 上,我们看到的此功能的常见 UI 组件是浮动搜索栏,放置在屏幕的显眼位置。在某些情况下,这还会向用户提供搜索建议,以简化搜索过程。Jetpack Compose Material3 软件包提供了对提供此功能的 SearchBar 可组合项的访问,在这篇博文中,我们将学习如何在我们自己的应用中使用它。

SearchBar 可组合项允许我们显示一个浮动的搜索组件,该组件展开后会显示可选的推荐。如上所述,这是我们在许多应用中看到的常见模式,此可组合项提供了开箱即用的解决方案。SearchBar 可组合项提供了足够的自定义功能来控制组件的外观和感觉,同时使用基于插槽(slot)的方法让我们提供输入字段以供使用。

Kotlin 复制代码
@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 参数,用于为实现提供展开状态的更新值(然后可用于反映我们自己的状态实现)。

Kotlin 复制代码
var expanded by remember { mutableStateOf(false) }

SearchBar(
    modifier = Modifier.fillMaxWidth(),
    expanded = expanded,
    onExpandedChange = {
        expanded = it
    }
)

除了管理这种展开状态外,我们还需要提供用于 SearchBar 输入区域的 inputField。除了遵循可组合项的基于插槽的方法之外,这还允许可组合项遵循状态提升的概念,使我们能够完全管理 SearchBar 输入字段的状态概念。

Kotlin 复制代码
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 在单击取消按钮时恢复到折叠状态。

Kotlin 复制代码
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 参数中。

Kotlin 复制代码
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 的展开状态将重置。

Kotlin 复制代码
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 中更广泛的组件支持来节省时间!

欢迎搜索并关注 公众号「稀有猿诉」 获取更多的优质文章!

保护原创,请勿转载!

相关推荐
泥嚎泥嚎20 小时前
【Android】给App添加启动画面——SplashScreen
android·java
全栈派森20 小时前
初见 Dart:这门新语言如何让你的 App「动」起来?
android·flutter·ios
q***985220 小时前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
恋猫de小郭20 小时前
Dart 3.10 发布,快来看有什么更新吧
android·前端·flutter
恋猫de小郭1 天前
Flutter 3.38 发布,快来看看有什么更新吧
android·前端·flutter
百锦再1 天前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子1 天前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师1 天前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588
精装机械师1 天前
在IntelliJ IDEA编辑器中基于Gradle编译器搭建Kotlin开发环境遇到的各种坑
kotlin·gradle·intellij-idea
江上清风山间明月1 天前
Android 系统超级实用的分析调试命令
android·内存·调试·dumpsys