鸿蒙PC UI控件库 - ButtonGroup 按钮组详解
本文介绍了ButtonGroup组件,这是一个支持单选和多选模式的按钮组控件。组件具有统一视觉设计,提供三种尺寸(small/medium/large),支持图标显示和禁用状态,左下角自动包含品牌标识。文章详细说明了组件的API接口、使用示例和主题配置方法,适用于筛选条件、选项选择等多种场景。通过代码示例展示了基础单选、多选、带图标和不同尺寸的按钮组实现方式。该组件所有样式均可通过代码配置,便于开
视频演示地址:
https://www.bilibili.com/video/BV1jomdBBE4H/
📋 目录
概述
ButtonGroup 是控件库中的按钮组组件,将多个按钮组合在一起,支持单选和多选两种模式,适用于选项选择、筛选、状态切换等场景。
设计理念
按钮组采用统一视觉设计,具有以下特点:
- 组合设计:多个按钮无缝连接,形成统一的视觉整体
- 模式灵活:支持单选(single)和多选(multiple)两种模式
- 尺寸多样:支持 small、medium、large 三种尺寸
- 状态清晰:选中状态使用主色背景,未选中状态使用次要背景
- 品牌标识:左下角自动包含品牌标识(圆圈红字"PC")
- 主题统一:所有样式配置都在代码中,方便定制
适用场景
- 筛选条件:时间筛选、状态筛选、类型筛选
- 选项选择:单选选项、多选选项
- 状态切换:启用/禁用、显示/隐藏
- 标签选择:分类标签、属性标签
特性
✨ 核心特性
- ✅ 单选模式:支持单选模式,只能选择一个选项
- ✅ 多选模式:支持多选模式,可以选择多个选项
- ✅ 图标支持:支持文字图标(textIcon)和图片图标(icon)
- ✅ 多种尺寸:支持 small、medium、large 三种尺寸
- ✅ 禁用状态:支持整体禁用和单项禁用
- ✅ 品牌标识:自动包含左下角品牌标识
- ✅ 主题配置:所有样式都可通过代码配置
🎨 视觉特点
- 选中状态:主色背景 + 白色文字
- 未选中状态:次要背景 + 主色文字
- 禁用状态:灰色背景 + 灰色文字 + 50% 透明度
- 无缝连接:按钮之间无缝连接,形成统一整体
- 圆角设计:整体使用圆角,内部按钮无圆角
快速开始
基础用法
import { ButtonGroup, ButtonGroupItem } from '../components/base'
@Entry
@Component
struct MyPage {
@State selectedValue: string | number = 'option1'
private items: ButtonGroupItem[] = [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' },
{ label: '选项3', value: 'option3' }
]
build() {
Column({ space: 20 }) {
// 单选模式
ButtonGroup({
items: this.items,
mode: 'single'
})
// 多选模式
ButtonGroup({
items: this.items,
mode: 'multiple'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
关于状态管理
ButtonGroup 使用内部状态管理选中值。如果需要外部控制选中值,可以通过监听点击事件或使用状态管理来实现。
API 参考
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
items |
ButtonGroupItem[] |
[] |
按钮项列表(必需) |
mode |
'single' | 'multiple' |
'single' |
选择模式:单选或多选 |
buttonSize |
'small' | 'medium' | 'large' |
'medium' |
按钮尺寸 |
showBrand |
boolean |
true |
是否显示品牌标识 |
disabled |
boolean |
false |
是否禁用整个按钮组 |
ButtonGroupItem 接口
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label |
string |
- | 按钮文字(必需) |
value |
string | number |
- | 按钮值(必需) |
disabled |
boolean? |
undefined |
是否禁用该项 |
icon |
ResourceStr? |
undefined |
图片图标(可选) |
textIcon |
string? |
undefined |
文字图标(可选,优先级高于 icon) |
尺寸规格
| 尺寸 | 按钮高度 | 字体大小 | 图标大小 | 内边距 |
|---|---|---|---|---|
small |
28vp | 12vp | 14vp | 12vp(左右) |
medium |
36vp | 14vp | 16vp | 16vp(左右) |
large |
44vp | 16vp | 20vp | 20vp(左右) |
使用示例
1. 基础单选按钮组
@Entry
@Component
struct ButtonGroupExample1 {
private items: ButtonGroupItem[] = [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' },
{ label: '选项3', value: 'option3' }
]
build() {
Column({ space: 15 }) {
ButtonGroup({
items: this.items,
mode: 'single'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
2. 多选按钮组
@Entry
@Component
struct ButtonGroupExample2 {
private items: ButtonGroupItem[] = [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' },
{ label: '选项3', value: 'option3' }
]
build() {
Column({ space: 15 }) {
ButtonGroup({
items: this.items,
mode: 'multiple'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
3. 带图标的按钮组
@Entry
@Component
struct ButtonGroupExample3 {
private items: ButtonGroupItem[] = [
{ label: '全部', value: 'all', textIcon: 'A' },
{ label: '待处理', value: 'pending', textIcon: 'P' },
{ label: '已完成', value: 'completed', textIcon: '√' }
]
build() {
Column({ space: 15 }) {
ButtonGroup({
items: this.items,
mode: 'single'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
4. 不同尺寸
@Entry
@Component
struct ButtonGroupExample4 {
private items: ButtonGroupItem[] = [
{ label: '小', value: 'small' },
{ label: '中', value: 'medium' },
{ label: '大', value: 'large' }
]
build() {
Column({ space: 20 }) {
ButtonGroup({
items: this.items,
mode: 'single',
buttonSize: 'small'
})
ButtonGroup({
items: this.items,
mode: 'single',
buttonSize: 'medium'
})
ButtonGroup({
items: this.items,
mode: 'single',
buttonSize: 'large'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
5. 禁用状态
@Entry
@Component
struct ButtonGroupExample5 {
private items: ButtonGroupItem[] = [
{ label: '可用', value: 'available' },
{ label: '不可用', value: 'unavailable', disabled: true },
{ label: '维护中', value: 'maintenance' }
]
build() {
Column({ space: 20 }) {
// 整个按钮组禁用
ButtonGroup({
items: this.items,
mode: 'single',
disabled: true
})
Divider()
.margin({ top: 20, bottom: 20 })
// 部分按钮禁用
ButtonGroup({
items: this.items,
mode: 'single'
})
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
6. 筛选场景
@Entry
@Component
struct FilterExample {
build() {
Column({ space: 20 }) {
// 时间筛选
Column({ space: 10 }) {
Text('时间筛选:')
.fontSize(16)
.fontColor('#111827')
.width('100%')
ButtonGroup({
items: [
{ label: '全部', value: 'all' },
{ label: '今天', value: 'today' },
{ label: '本周', value: 'week' },
{ label: '本月', value: 'month' }
],
mode: 'single',
buttonSize: 'medium'
})
}
.width('100%')
}
.width('100%')
.height('100%')
.padding(20)
}
}
7. 状态选择场景
@Entry
@Component
struct StatusExample {
build() {
Column({ space: 20 }) {
// 订单状态(多选)
Column({ space: 10 }) {
Text('订单状态(多选):')
.fontSize(16)
.fontColor('#111827')
.width('100%')
ButtonGroup({
items: [
{ label: '待付款', value: 'unpaid', textIcon: 'P' },
{ label: '待发货', value: 'unshipped', textIcon: 'S' },
{ label: '已发货', value: 'shipped', textIcon: '√' },
{ label: '已完成', value: 'completed', textIcon: 'C' }
],
mode: 'multiple',
buttonSize: 'medium'
})
}
.width('100%')
}
.width('100%')
.height('100%')
.padding(20)
}
}
主题配置
ButtonGroup 的所有样式都通过 ComponentTheme 配置,所有配置都在代码中,不依赖JSON文件。
修改默认颜色
import { ComponentTheme } from '../theme/ComponentTheme'
// 修改主色(影响选中状态的背景色)
ComponentTheme.PRIMARY_COLOR = '#007AFF'
// 修改次要背景色(影响未选中状态的背景色)
ComponentTheme.BACKGROUND_SECONDARY = '#F5F5F5'
// 修改边框颜色
ComponentTheme.BORDER_COLOR = '#E5E5E5'
// 修改圆角
ComponentTheme.BORDER_RADIUS = 8
批量配置
import { ComponentTheme } from '../theme/ComponentTheme'
// 使用 setTheme 方法批量配置
ComponentTheme.setTheme({
primaryColor: '#007AFF',
borderRadius: 8,
spacing: 16
})
最佳实践
1. 模式选择
推荐:根据使用场景选择模式
- 单选模式(single):用于互斥选项,如时间筛选、状态切换
- 多选模式(multiple):用于可多选的选项,如标签选择、属性筛选
2. 尺寸选择
- small:用于紧凑空间、工具栏
- medium:默认尺寸,适用于大多数场景
- large:用于重要操作或大屏幕显示
3. 选项数量
- 建议选项数量在 2-5 个之间
- 选项过多时考虑使用下拉菜单或其他组件
- 选项文字保持简洁,避免过长
4. 图标使用
- 使用文字图标(textIcon)确保兼容性
- 图标应与文字含义相关
- 保持图标风格统一
5. 禁用状态
- 使用整体禁用(disabled)控制整个按钮组
- 使用单项禁用(item.disabled)控制单个选项
- 禁用状态应清晰可见
6. 响应式设计
- 在小屏幕上考虑使用 smaller 尺寸
- 保持按钮之间的合理间距
- 确保触摸目标足够大(至少 28vp)
常见问题
Q1: ButtonGroup 和其他按钮有什么区别?
A: 主要区别在于使用场景:
- PrimaryButton/SecondaryButton/TextButton/IconButton:单个按钮,用于操作
- ButtonGroup:多个按钮组合,用于选项选择、筛选
ButtonGroup 更适合需要从多个选项中选择的场景。
Q2: 什么时候使用单选,什么时候使用多选?
A: 根据业务需求选择:
- 单选模式(single):选项互斥,只能选择一个,如时间筛选、状态切换
- 多选模式(multiple):选项不互斥,可以选择多个,如标签选择、属性筛选
Q3: 如何获取选中的值?
A: ButtonGroup 使用内部状态管理。如果需要外部获取选中值,可以通过以下方式:
- 监听点击事件:在按钮点击时获取值
- 状态管理:使用全局状态管理(如 Redux、MobX)
- 自定义事件:创建自定义事件系统
Q4: 可以动态更新选项吗?
A: 可以。通过更新 items 数组来动态更新选项:
@State items: ButtonGroupItem[] = [
{ label: '选项1', value: 'option1' }
]
// 动态添加选项
this.items.push({ label: '选项2', value: 'option2' })
this.items = [...this.items] // 触发更新
Q5: 如何自定义按钮样式?
A: 可以通过 ComponentTheme 自定义全局样式:
ComponentTheme.PRIMARY_COLOR = '#34C759' // 选中状态背景色
ComponentTheme.BACKGROUND_SECONDARY = '#F0F0F0' // 未选中状态背景色
ComponentTheme.BORDER_RADIUS = 12 // 圆角大小
Q6: 按钮组可以垂直排列吗?
A: 当前版本支持水平排列。如果需要垂直排列,可以:
- 使用多个
ButtonGroup垂直排列 - 自定义实现垂直布局的按钮组
总结
ButtonGroup 是控件库中的按钮组组件,具有以下核心特性:
- 组合设计:多个按钮无缝连接,形成统一整体
- 模式灵活:支持单选和多选两种模式
- 尺寸多样:三种尺寸满足不同场景需求
- 功能完整:支持图标、禁用等多种功能
- 易于使用:简单的 API,开箱即用
- 主题配置:所有样式都可通过代码配置
- 品牌标识:自动包含品牌标识,保持视觉统一
关键要点
- ✅ 使用
mode属性选择单选或多选模式 - ✅ 使用
buttonSize属性选择合适尺寸 - ✅ 使用
items属性配置按钮项 - ✅ 使用
disabled属性控制按钮组状态 - ✅ 使用
textIcon或icon添加图标 - ✅ 通过
ComponentTheme自定义全局样式
适用场景
- 筛选条件选择
- 选项选择
- 状态切换
- 标签选择
- 属性筛选
下一篇预告:TextInput(文本输入框)详解
本文档属于《鸿蒙PC UI控件库开发系列文章》第6篇
更多推荐



所有评论(0)