视频演示地址:
https://www.bilibili.com/video/BV1jomdBBE4H/
📋 目录
- 概述
- 特性
- 快速开始
- API 参考
- 使用示例
- 主题配置
- 最佳实践
- 常见问题
- 总结
概述
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'privateitems: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{privateitems: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{privateitems: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{privateitems: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{privateitems: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{privateitems: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篇