鸿蒙PC UI控件库 - IconButton 图标按钮详解

视频演示地址:

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

📋 目录


概述

IconButton 是控件库中的图标按钮组件,仅显示图标,无文字,适用于工具栏、操作按钮等场景。与文字按钮的主要区别在于:

  • PrimaryButton/SecondaryButton/TextButton:显示文字(可带图标)
  • IconButton:仅显示图标,无文字

设计理念

图标按钮采用极简设计,具有以下特点:

  1. 纯图标设计:仅显示图标,节省空间
  2. 形状灵活:支持圆形和方形两种形状
  3. 尺寸多样:支持 small、medium、large 三种尺寸(large 尺寸为 80vp × 80vp,图标 40vp)
  4. 品牌标识:左下角自动包含品牌标识(圆圈红字"PC")
  5. 主题统一:所有样式配置都在代码中,方便定制
  6. 通用字符:使用 ASCII 字符作为图标,确保在所有系统上都能正确显示

图标字符映射

为了确保图标在所有系统上都能正确显示,推荐使用以下 ASCII 字符:

字符含义用途
SSettings(设置)设置、配置相关操作
UUser(用户)用户、账户相关操作
RRefresh(刷新)刷新、重新加载
DDelete(删除)删除操作
EEdit(编辑)编辑、修改操作
+Add(添加)添加、新建操作
Check(确认)确认、成功操作
×Close(关闭)关闭、取消操作
...More(更多)更多选项
BBold(粗体)文本格式化
IItalic(斜体)文本格式化
< = >对齐左对齐、居中、右对齐

特性

✨ 核心特性

  • 纯图标设计:仅显示图标,无文字
  • 多种形状:支持圆形(circle)和方形(square)
  • 多种尺寸:支持 small、medium、large 三种尺寸(large 尺寸为 80vp × 80vp,图标 40vp)
  • 加载状态:内置加载动画
  • 禁用状态:支持禁用状态,自动调整样式
  • 自定义颜色:支持自定义图标颜色和背景颜色
  • 品牌标识:自动包含左下角品牌标识
  • 主题配置:所有样式都可通过代码配置

🎨 视觉特点

  • 圆形按钮:完全圆形,适合工具栏和操作按钮
  • 方形按钮:圆角方形,适合列表操作和卡片操作
  • 正常状态:图标颜色为主题主色,背景透明
  • 悬停状态:背景色变化(通过系统自动处理)
  • 禁用状态:图标变灰 + 50% 透明度

快速开始

基础用法

import { IconButton } from '../components/base'

@Entry
@Component
struct MyPage {
  build() {
    Column({ space: 20 }) {
      // 基础圆形图标按钮(使用文字图标)
      IconButton({
        textIcon: 'S'  // S = Settings(设置)
      })
      
      // 方形图标按钮
      IconButton({
        textIcon: '...',  // ... = More(更多)
        shape: 'square'
      })
      
      // 不同尺寸
      Row({ space: 12 }) {
        IconButton({
          textIcon: '+',
          buttonSize: 'small'
        })
        
        IconButton({
          textIcon: '+',
          buttonSize: 'medium'
        })
        
        IconButton({
          textIcon: '+',
          buttonSize: 'large'
        })
      }
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

关于点击事件处理

IconButtononClickBuilder 属性是 @BuilderParam 类型,需要使用 @Builder@LocalBuilder 方法初始化。在实际项目中,推荐使用以下方式处理点击事件:

  1. 状态管理方式:通过 @State 变量和普通 ButtononClick 来处理
  2. 自定义事件系统:创建自定义事件处理机制
  3. @Builder 方法:如果需要使用 onClickBuilder,需要定义 @Builder 方法

本文档中的示例主要展示按钮的视觉效果和样式配置,点击事件处理可以通过上述方式实现。


API 参考

Props

属性名类型默认值说明
iconResourceStr?undefined按钮图标(可选,图片资源)
textIconstring?undefined文字图标(可选,ASCII字符或Unicode字符,优先级高于 icon。推荐使用:S=设置, U=用户, R=刷新, D=删除, E=编辑, +=添加, √=确认, ×=关闭)
shape'circle' | 'square''circle'按钮形状
buttonSize'small' | 'medium' | 'large''medium'按钮尺寸
loadingbooleanfalse是否加载中
disabledbooleanfalse是否禁用
showBrandbooleantrue是否显示品牌标识
iconColorstring?undefined图标颜色(可选,默认使用主题色)
buttonBackgroundColorstring?undefined背景颜色(可选,默认透明)
onClickBuilder@BuilderParam () => void?undefined点击事件回调(需要使用 @Builder 或 @LocalBuilder 方法)

尺寸规格

尺寸按钮大小图标大小圆角(圆形)圆角(方形)
small32vp × 32vp16vp16vp4vp
medium40vp × 40vp20vp20vp8vp
large80vp × 80vp40vp40vp12vp

使用示例

1. 基础按钮

@Entry
@Component
struct ButtonExample1 {
  build() {
    Column({ space: 15 }) {
      // 圆形图标按钮(使用文字图标)
      IconButton({
        textIcon: 'S'  // S = Settings(设置)
      })
      
      // 方形图标按钮
      IconButton({
        textIcon: '...',  // ... = More(更多)
        shape: 'square'
      })
      
      // 带背景的图标按钮
      IconButton({
        textIcon: '+',  // + = Add(添加)
        buttonBackgroundColor: '#F0F7FF'
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

2. 不同尺寸

@Entry
@Component
struct ButtonExample2 {
  build() {
    Column({ space: 15 }) {
      Row({ space: 12 }) {
        IconButton({
          textIcon: 'S',  // S = Settings(设置)
          buttonSize: 'small'
        })
        
        IconButton({
          textIcon: 'S',
          buttonSize: 'medium'
        })
        
        IconButton({
          textIcon: 'S',
          buttonSize: 'large'
        })
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

3. 不同形状

@Entry
@Component
struct ButtonExample3 {
  build() {
    Column({ space: 15 }) {
      Row({ space: 12 }) {
        // 圆形按钮
        IconButton({
          textIcon: 'U',  // U = User(用户)
          shape: 'circle'
        })
        
        // 方形按钮
        IconButton({
          textIcon: 'U',
          shape: 'square'
        })
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

4. 自定义颜色

@Entry
@Component
struct ButtonExample4 {
  build() {
    Column({ space: 15 }) {
      Row({ space: 12 }) {
        // 默认颜色
        IconButton({
          textIcon: 'S'  // S = Settings(设置)
        })
        
        // 自定义图标颜色
        IconButton({
          textIcon: '√',  // √ = Check(确认/成功)
          iconColor: '#34C759'
        })
        
        // 自定义背景颜色
        IconButton({
          textIcon: 'S',
          buttonBackgroundColor: '#F0F7FF'
        })
        
        // 自定义图标和背景颜色
        IconButton({
          textIcon: '×',  // × = Close(关闭/删除)
          iconColor: '#FF3B30',
          buttonBackgroundColor: '#FFEBEE'
        })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

5. 加载状态

@Entry
@Component
struct ButtonExample5 {
  @State loading: boolean = false
  
  // 处理加载操作
  handleLoad() {
    this.loading = true
    // 模拟异步操作
    setTimeout(() => {
      this.loading = false
      console.info('加载完成')
    }, 2000)
  }
  
  build() {
    Column({ space: 20 }) {
      IconButton({
        textIcon: 'R',  // R = Refresh(刷新)
        loading: this.loading
      })
      
      // 使用普通按钮触发加载状态
      Button() {
        Text(this.loading ? '加载中...' : '点击刷新')
      }
      .onClick(() => {
        this.handleLoad()
      })
      .enabled(!this.loading)
      
      Text('点击按钮查看加载状态')
        .fontSize(12)
        .fontColor('#999999')
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

6. 禁用状态

@Entry
@Component
struct ButtonExample6 {
  @State canDelete: boolean = false
  
  build() {
    Column({ space: 20 }) {
      IconButton({
        textIcon: 'D',  // D = Delete(删除)
        disabled: !this.canDelete
      })
      
      Row({ space: 10 }) {
        Text('删除权限:')
          .fontSize(14)
        Toggle({ type: ToggleType.Switch, isOn: this.canDelete })
          .onChange((isOn: boolean) => {
            this.canDelete = isOn
          })
        Text(this.canDelete ? '已开启' : '已关闭')
          .fontSize(14)
          .fontColor(this.canDelete ? '#10B981' : '#EF4444')
      }
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

7. 工具栏场景

@Entry
@Component
struct ToolbarExample {
  build() {
    Column({ space: 20 }) {
      // 工具栏
      Row({ space: 8 }) {
        IconButton({
          textIcon: 'B',
          buttonSize: 'small',
          shape: 'square'
        })
        
        IconButton({
          textIcon: 'I',
          buttonSize: 'small',
          shape: 'square'
        })
        
        IconButton({
          textIcon: 'U',
          buttonSize: 'small',
          shape: 'square'
        })
        
        Divider()
          .vertical(true)
          .height(24)
          .margin({ left: 8, right: 8 })
        
        IconButton({
          textIcon: '<',  // < = 左对齐
          buttonSize: 'small',
          shape: 'square'
        })
        
        IconButton({
          textIcon: '=',  // = = 居中对齐
          buttonSize: 'small',
          shape: 'square'
        })
        
        IconButton({
          textIcon: '>',  // > = 右对齐
          buttonSize: 'small',
          shape: 'square'
        })
      }
      .width('100%')
      .padding(12)
      .backgroundColor('#F9FAFB')
      .borderRadius(8)
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

8. 列表操作场景

@Entry
@Component
struct ListActionExample {
  build() {
    Column({ space: 20 }) {
      // 列表项操作
      Row({ space: 12 }) {
        Text('文件名称.txt')
          .fontSize(14)
          .layoutWeight(1)
        
        IconButton({
          textIcon: 'E',  // E = Edit(编辑)
          buttonSize: 'small',
          shape: 'square'
        })
        
        IconButton({
          textIcon: 'D',  // D = Delete(删除)
          buttonSize: 'small',
          shape: 'square',
          iconColor: '#FF3B30'
        })
      }
      .width('100%')
      .padding(12)
      .backgroundColor('#FFFFFF')
      .borderRadius(8)
      .shadow({ radius: 4, color: '#00000010', offsetX: 0, offsetY: 2 })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

9. 卡片操作场景

@Entry
@Component
struct CardActionExample {
  build() {
    Column({ space: 20 }) {
      // 卡片右上角操作
      Stack() {
        Column({ space: 8 }) {
          Text('卡片标题')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
          
          Text('卡片内容描述')
            .fontSize(14)
            .fontColor('#666666')
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        
        IconButton({
          textIcon: '...',  // ... = More(更多)
          buttonSize: 'small',
          shape: 'circle'
        })
        .align(Alignment.TopEnd)
      }
      .width('100%')
      .padding(16)
      .backgroundColor('#FFFFFF')
      .borderRadius(12)
      .shadow({ radius: 4, color: '#00000010', offsetX: 0, offsetY: 2 })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

10. 按钮组合

@Entry
@Component
struct ButtonGroupExample {
  build() {
    Column({ space: 20 }) {
      // 操作按钮组
      Row({ space: 12 }) {
        IconButton({
          textIcon: '+',
          buttonSize: 'medium',
          shape: 'circle',
          buttonBackgroundColor: '#F0F7FF'
        })
        
        IconButton({
          textIcon: 'E',  // E = Edit(编辑)
          buttonSize: 'medium',
          shape: 'circle'
        })
        
        IconButton({
          textIcon: 'D',  // D = Delete(删除)
          buttonSize: 'medium',
          shape: 'circle',
          iconColor: '#FF3B30'
        })
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

主题配置

IconButton 的所有样式都通过 ComponentTheme 配置,所有配置都在代码中,不依赖JSON文件。

修改默认颜色

import { ComponentTheme } from '../theme/ComponentTheme'

// 修改主题主色(影响 IconButton 的默认图标颜色)
ComponentTheme.PRIMARY_COLOR = '#007AFF'

// 修改文字主色(影响 IconButton 的默认图标颜色)
ComponentTheme.TEXT_PRIMARY = '#000000'

// 修改禁用文字颜色
ComponentTheme.TEXT_DISABLED = '#CCCCCC'

// 修改背景次要色(影响禁用状态的背景)
ComponentTheme.BACKGROUND_SECONDARY = '#F5F5F5'

批量配置

import { ComponentTheme } from '../theme/ComponentTheme'

// 使用 setTheme 方法批量配置
ComponentTheme.setTheme({
  primaryColor: '#007AFF',
  borderRadius: 8,
  spacing: 16
})

自定义主题

// 在应用启动时配置
import { ComponentTheme } from './theme/ComponentTheme'

// 设置自定义主色
ComponentTheme.TEXT_PRIMARY = '#34C759'  // 绿色

最佳实践

1. 形状选择

推荐:根据使用场景选择形状

  • 圆形(circle):用于工具栏、浮动操作按钮、卡片操作
  • 方形(square):用于列表操作、表格操作、紧凑空间

2. 尺寸选择

  • small:用于工具栏、列表操作、表格操作
  • medium:默认尺寸,适用于大多数场景
  • large:用于重要操作或大屏幕显示

3. 颜色使用

  • 默认使用主题主色,保持视觉统一
  • 危险操作使用红色(如删除按钮)
  • 特殊操作可使用自定义颜色
  • 避免在同一页面使用过多不同颜色

4. 图标选择

  • 推荐使用 ASCII 字符:确保在所有系统上都能正确显示
  • 字符映射:使用标准字符映射(S=设置, U=用户, R=刷新, D=删除, E=编辑, +=添加, √=确认, ×=关闭)
  • 清晰易识别:选择清晰、易识别的字符
  • 尺寸适配:确保图标在不同尺寸下都清晰可见(large 尺寸图标为 40vp)

5. 工具栏使用

  • 将相关操作分组
  • 使用分隔线区分不同功能组
  • 保持一致的尺寸和形状

6. 响应式设计

  • 在小屏幕上考虑使用 smaller 尺寸
  • 保持按钮之间的合理间距
  • 确保触摸目标足够大(至少 32vp)

常见问题

Q1: IconButton 和其他按钮有什么区别?

A: 主要区别在于显示内容:

  • PrimaryButton/SecondaryButton/TextButton:显示文字(可带图标)
  • IconButton:仅显示图标,无文字

IconButton 更适合工具栏、操作按钮等需要节省空间的场景。

Q2: 什么时候使用圆形,什么时候使用方形?

A: 根据使用场景选择:

  • 圆形(circle):工具栏、浮动操作按钮、卡片操作、需要突出显示的操作
  • 方形(square):列表操作、表格操作、紧凑空间、需要对齐的场景

Q3: 如何自定义按钮颜色?

A: 有两种方式:

  1. 通过 iconColor 和 buttonBackgroundColor 属性(单个按钮):
IconButton({
  textIcon: 'S',  // S = Settings(设置)
  iconColor: '#34C759',
  buttonBackgroundColor: '#F0F9F4'
})
  1. 通过 ComponentTheme(全局配置):
ComponentTheme.TEXT_PRIMARY = '#34C759'
ComponentTheme.BACKGROUND_SECONDARY = '#F0F9F4'

Q4: 如何处理按钮点击事件?

A: onClickBuilder@BuilderParam 类型,需要使用 @Builder@LocalBuilder 方法。推荐使用状态管理或自定义事件系统:

@Entry
@Component
struct MyPage {
  @State count: number = 0
  
  handleClick() {
    this.count++
    console.info('按钮被点击')
  }
  
  build() {
    Column({ space: 20 }) {
      // 使用普通按钮处理点击
      Button() {
        Image($r('app.media.icon_settings'))
          .width(20)
          .height(20)
      }
      .onClick(() => {
        this.handleClick()
      })
      
      // 使用 IconButton 展示样式
      IconButton({
        textIcon: 'S'  // S = Settings(设置)
      })
      
      Text(`点击次数:${this.count}`)
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

Q5: IconButton 可以用于工具栏吗?

A: 可以。IconButton 非常适合用于工具栏场景:

Row({ space: 8 }) {
  IconButton({
    textIcon: 'B',  // B = Bold(粗体)
    buttonSize: 'small',
    shape: 'square'
  })
  IconButton({
    textIcon: 'I',  // I = Italic(斜体)
    buttonSize: 'small',
    shape: 'square'
  })
}

Q6: 按钮大小可以自定义吗?

A: 目前支持三种预设尺寸(small、medium、large)。如果需要自定义大小,可以通过修改 ComponentTheme 中的相关配置,或者使用其他按钮组件(如 TextButton)配合图标实现。


总结

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

  1. 纯图标设计:仅显示图标,节省空间
  2. 形状灵活:支持圆形和方形两种形状
  3. 尺寸多样:三种尺寸满足不同场景需求
  4. 功能完整:支持加载、禁用等多种状态
  5. 易于使用:简单的 API,开箱即用
  6. 主题配置:所有样式都可通过代码配置
  7. 品牌标识:自动包含品牌标识,保持视觉统一

关键要点

  • ✅ 使用 shape 属性选择合适形状
  • ✅ 使用 buttonSize 属性选择合适尺寸
  • ✅ 使用 iconColorbuttonBackgroundColor 自定义颜色
  • ✅ 使用 loading 属性处理异步操作
  • ✅ 使用 disabled 属性控制按钮状态
  • ✅ 通过 ComponentTheme 自定义全局样式

适用场景

  • 工具栏操作按钮
  • 列表项操作按钮
  • 卡片操作按钮
  • 表格操作按钮
  • 浮动操作按钮
  • 需要节省空间的按钮场景

下一篇预告:ButtonGroup(按钮组)详解


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

红目香薰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值