鸿蒙PC UI控件库 - ButtonGroup 按钮组详解

视频演示地址:

https://www.bilibili.com/video/BV1jomdBBE4H/
在这里插入图片描述

📋 目录


概述

ButtonGroup 是控件库中的按钮组组件,将多个按钮组合在一起,支持单选和多选两种模式,适用于选项选择、筛选、状态切换等场景。

设计理念

按钮组采用统一视觉设计,具有以下特点:

  1. 组合设计:多个按钮无缝连接,形成统一的视觉整体
  2. 模式灵活:支持单选(single)和多选(multiple)两种模式
  3. 尺寸多样:支持 small、medium、large 三种尺寸
  4. 状态清晰:选中状态使用主色背景,未选中状态使用次要背景
  5. 品牌标识:左下角自动包含品牌标识(圆圈红字"PC")
  6. 主题统一:所有样式配置都在代码中,方便定制

适用场景

  • 筛选条件:时间筛选、状态筛选、类型筛选
  • 选项选择:单选选项、多选选项
  • 状态切换:启用/禁用、显示/隐藏
  • 标签选择:分类标签、属性标签

特性

✨ 核心特性

  • 单选模式:支持单选模式,只能选择一个选项
  • 多选模式:支持多选模式,可以选择多个选项
  • 图标支持:支持文字图标(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

属性名类型默认值说明
itemsButtonGroupItem[][]按钮项列表(必需)
mode'single' | 'multiple''single'选择模式:单选或多选
buttonSize'small' | 'medium' | 'large''medium'按钮尺寸
showBrandbooleantrue是否显示品牌标识
disabledbooleanfalse是否禁用整个按钮组

ButtonGroupItem 接口

属性名类型默认值说明
labelstring-按钮文字(必需)
valuestring | number-按钮值(必需)
disabledboolean?undefined是否禁用该项
iconResourceStr?undefined图片图标(可选)
textIconstring?undefined文字图标(可选,优先级高于 icon)

尺寸规格

尺寸按钮高度字体大小图标大小内边距
small28vp12vp14vp12vp(左右)
medium36vp14vp16vp16vp(左右)
large44vp16vp20vp20vp(左右)

使用示例

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 使用内部状态管理。如果需要外部获取选中值,可以通过以下方式:

  1. 监听点击事件:在按钮点击时获取值
  2. 状态管理:使用全局状态管理(如 Redux、MobX)
  3. 自定义事件:创建自定义事件系统

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: 当前版本支持水平排列。如果需要垂直排列,可以:

  1. 使用多个 ButtonGroup 垂直排列
  2. 自定义实现垂直布局的按钮组

总结

ButtonGroup 是控件库中的按钮组组件,具有以下核心特性:

  1. 组合设计:多个按钮无缝连接,形成统一整体
  2. 模式灵活:支持单选和多选两种模式
  3. 尺寸多样:三种尺寸满足不同场景需求
  4. 功能完整:支持图标、禁用等多种功能
  5. 易于使用:简单的 API,开箱即用
  6. 主题配置:所有样式都可通过代码配置
  7. 品牌标识:自动包含品牌标识,保持视觉统一

关键要点

  • ✅ 使用 mode 属性选择单选或多选模式
  • ✅ 使用 buttonSize 属性选择合适尺寸
  • ✅ 使用 items 属性配置按钮项
  • ✅ 使用 disabled 属性控制按钮组状态
  • ✅ 使用 textIconicon 添加图标
  • ✅ 通过 ComponentTheme 自定义全局样式

适用场景

  • 筛选条件选择
  • 选项选择
  • 状态切换
  • 标签选择
  • 属性筛选

下一篇预告:TextInput(文本输入框)详解


本文档属于《鸿蒙PC UI控件库开发系列文章》第6篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红目香薰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值