项目简介
rchoui 是一个面向 HarmonyOS6 的企业级 UI 组件库,旨在提供开箱即用的高质量组件,让开发者告别'重复造轮子'。
HarmonyOS6 RcIcon 组件提供丰富的符号图标支持,涵盖基础用法、尺寸系统、颜色配置、双风格切换、圆角设置及动画效果。通过 IconName 常量实现类型安全引用,支持线型与实底风格对比,适配响应式布局。文档包含工具栏导航、状态指示、底部导航、用户头像等 10 个实战场景,展示点击交互与性能优化方案。帮助开发者建立统一设计规范,减少资源体积,提升 UI 开发效率与用户体验。

rchoui 是一个面向 HarmonyOS6 的企业级 UI 组件库,旨在提供开箱即用的高质量组件,让开发者告别'重复造轮子'。
本文档基于 RcIcon 组件的完整实战案例集,通过 10 个典型应用场景,展示如何在真实项目中灵活运用字体符号组件。每个案例都包含完整的代码实现、效果说明和最佳实践建议,帮助开发者快速掌握 RcIcon 组件的实战技巧。
适用读者: HarmonyOS6 应用开发者、UI/UX 工程师、前端架构师
核心内容:
RcIcon 组件提供了多种符号引用方式,满足不同开发场景需求:
import { RcIcon, IconName } from "rchoui"
@Component struct BasicUsageExample {
build() {
Row({ space: 20 }) {
// 方式 1: 使用 IconName 常量 (推荐)
RcIcon({ name: IconName.HOME })
// 方式 2: 使用线型风格常量
RcIcon({ name: IconName.HEART_OUTLINE })
// 方式 3: 使用实底风格常量
RcIcon({ name: IconName.STAR })
// 方式 4: 直接使用字符串名称
RcIcon({ name: 'icon-houi_search' })
}.width('100%').justifyContent(FlexAlign.SpaceAround).padding(20)
}
}
实战要点:
IconName 常量: 获得 IDE 自动补全和类型检查,避免拼写错误HOME 与 HOME_OUTLINE 配合使用,满足激活/未激活状态切换@Component struct QuickNavigationToolbar {
build() {
Row({ space: 15 }) {
RcIcon({ name: IconName.HOME }) // 首页入口
RcIcon({ name: IconName.HEART_OUTLINE }) // 收藏功能
RcIcon({ name: IconName.STAR }) // 关注列表
RcIcon({ name: 'icon-houi_search' }) // 搜索功能
}.width('100%').height(56).justifyContent(FlexAlign.SpaceEvenly).backgroundColor('#ffffff').border({ width: { top: 0.5 }, color: '#e0e0e0' })
}
}
使用效果: 快速构建包含 4 个常用功能的工具栏,代码简洁且易于维护。
RcIcon 支持数值和字符串两种尺寸设置方式,适配不同设备和场景:
@Component struct ResponsiveSizeExample {
build() {
Row({ space: 20 }) {
// 固定数值尺寸 (单位:vp)
RcIcon({ name: IconName.SETTINGS, iconSize: 16 }) // 小型 - 用于密集布局
RcIcon({ name: IconName.SETTINGS, iconSize: 24 }) // 常规 - 通用场景
RcIcon({ name: IconName.SETTINGS, iconSize: 32 }) // 中型 - 强调展示
RcIcon({ name: IconName.SETTINGS, iconSize: 48 }) // 大型 - 主要入口
// 响应式字符串尺寸
RcIcon({ name: IconName.SETTINGS, iconSize: '64vp' }) // 超大 - 引导页面
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
}
建立符号尺寸规范体系,确保整个应用的视觉一致性:
// 定义符号尺寸规范枚举
enum IconSizeSpec {
XS = 12, // 极小 - 徽章、标签
SM = 16, // 小 - 按钮内、表单前缀
MD = 24, // 中 - 列表、卡片
LG = 32, // 大 - 标签页、导航栏
XL = 48, // 超大 - 功能入口、空状态
XXL = 64 // 巨大 - 引导页、欢迎屏幕
}
@Component struct DesignSystemSizeDemo {
build() {
Column({ space: 30 }) {
// 场景 1: 列表项符号 - 使用 MD 尺寸
Row({ space: 12 }) {
RcIcon({ name: IconName.FILE_OUTLINE, iconSize: IconSizeSpec.MD })
Text('项目文档.pdf').fontSize(16)
}
// 场景 2: 按钮内符号 - 使用 SM 尺寸
Button() {
Row({ space: 6 }) {
RcIcon({ name: IconName.DOWNLOAD_OUTLINE, iconSize: IconSizeSpec.SM, color: '#ffffff' })
Text('下载').fontColor('#ffffff')
}
}.height(36).backgroundColor('#2196F3')
// 场景 3: 功能入口符号 - 使用 XL 尺寸
Column({ space: 8 }) {
RcIcon({ name: IconName.CAMERA_OUTLINE, iconSize: IconSizeSpec.XL, color: '#2196F3' })
Text('拍照上传').fontSize(14).fontColor('#666666')
}.justifyContent(FlexAlign.Center)
}.width('100%').padding(20)
}
}
最佳实践:
RcIcon 支持多种颜色设置方式,满足丰富的视觉需求:
@Component struct ColorSystemExample {
build() {
Row({ space: 20 }) {
// 十六进制颜色
RcIcon({ name: IconName.HEART, color: '#ff0000', // 红色 - 喜欢/收藏 iconSize: 32 })
// Color 枚举
RcIcon({ name: IconName.HEART, color: Color.Blue, // 蓝色 - 信息/链接 iconSize: 32 })
// RGB 颜色值
RcIcon({ name: IconName.HEART, color: '#ff6b6b', // 粉红 - 温馨/浪漫 iconSize: 32 })
// 品牌色
RcIcon({ name: IconName.HEART, color: '#00d4ff', // 青色 - 科技/现代 iconSize: 32 })
// 警示色
RcIcon({ name: IconName.HEART, color: '#ffa500', // 橙色 - 警告/提示 iconSize: 32 })
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
}
通过颜色快速传递系统状态信息:
// 定义状态颜色规范
class StatusColors {
static readonly SUCCESS = '#4CAF50' // 成功 - 绿色
static readonly ERROR = '#f44336' // 错误 - 红色
static readonly WARNING = '#ff9800' // 警告 - 橙色
static readonly INFO = '#2196F3' // 信息 - 蓝色
static readonly DEFAULT = '#666666' // 默认 - 灰色
}
@Component struct StatusIndicatorDemo {
@State orderStatus: 'pending' | 'success' | 'failed' = 'pending'
build() {
Column({ space: 20 }) {
// 订单状态展示
Row({ space: 12 }) {
RcIcon({ name: this.getStatusSymbol(), color: this.getStatusColor(), iconSize: 28 })
Text(this.getStatusText()).fontSize(16).fontColor(this.getStatusColor())
}.padding(16).backgroundColor('#f5f5f5').borderRadius(8)
// 状态切换按钮
Row({ space: 12 }) {
Button('模拟成功').onClick(() => this.orderStatus = 'success').backgroundColor(StatusColors.SUCCESS)
Button('模拟失败').onClick(() => this.orderStatus = 'failed').backgroundColor(StatusColors.ERROR)
Button('重置').onClick(() => this.orderStatus = 'pending').backgroundColor(StatusColors.DEFAULT)
}
}.width('100%').padding(20)
}
// 根据状态返回对应符号
private getStatusSymbol(): string {
const symbolMap = {
'pending': IconName.INFO_OUTLINE,
'success': IconName.CHECKMARK_CIRCLE_OUTLINE,
'failed': IconName.CLOSE_CIRCLE_OUTLINE
}
return symbolMap[this.orderStatus]
}
// 根据状态返回对应颜色
private getStatusColor(): string {
const colorMap = {
'pending': StatusColors.INFO,
'success': StatusColors.SUCCESS,
'failed': StatusColors.ERROR
}
return colorMap[this.orderStatus]
}
// 根据状态返回对应文本
private getStatusText(): string {
const textMap = {
'pending': '订单处理中',
'success': '订单已完成',
'failed': '订单已失败'
}
return textMap[this.orderStatus]
}
}
实战价值: 通过颜色和符号的组合,用户可以在 0.3 秒内识别系统状态,提升信息传达效率。
@Component struct DualStyleExample {
build() {
Column({ space: 15 }) {
// 线型风格 - 适合未激活/次要状态
Row({ space: 20 }) {
Text('线型:').fontSize(14).width(60).fontColor('#666666')
RcIcon({ name: IconName.HOME_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.HEART_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.STAR_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.PERSON_OUTLINE, iconSize: 28 })
}
// 实底风格 - 适合激活/主要状态
Row({ space: 20 }) {
Text('实底:').fontSize(14).width(60).fontColor('#666666')
RcIcon({ name: IconName.HOME, iconSize: 28 })
RcIcon({ name: IconName.HEART, iconSize: 28 })
RcIcon({ name: IconName.STAR, iconSize: 28 })
RcIcon({ name: IconName.PERSON, iconSize: 28 })
}
}.width('100%').padding(20).backgroundColor('#ffffff').borderRadius(8)
}
}
通过线型/实底风格切换实现标签页激活状态:
interface TabItem {
symbolOutline: string
symbolFilled: string
label: string
}
@Component struct BottomTabBarDemo {
@State activeTab: number = 0
private tabData: TabItem[] = [
{ symbolOutline: IconName.HOME_OUTLINE, symbolFilled: IconName.HOME, label: '首页' },
{ symbolOutline: IconName.SEARCH_OUTLINE, symbolFilled: IconName.SEARCH, label: '搜索' },
{ symbolOutline: IconName.PERSON_OUTLINE, symbolFilled: IconName.PERSON, label: '我的' },
{ symbolOutline: IconName.SETTINGS_OUTLINE, symbolFilled: IconName.SETTINGS, label: '设置' }
]
build() {
Row({ space: 0 }) {
ForEach(this.tabData, (item: TabItem, index: number) => {
Column({ space: 4 }) {
RcIcon({
name: this.activeTab === index ? item.symbolFilled : item.symbolOutline,
iconSize: 24,
color: this.activeTab === index ? '#2196F3' : '#999999',
onIconClick: () => {
this.activeTab = index
console.log(`切换到标签页:${item.label}`)
}
})
Text(item.label).fontSize(11).fontColor(this.activeTab === index ? '#2196F3' : '#999999')
}.width(`${100 / this.tabData.length}%`).height(56).justifyContent(FlexAlign.Center)
})
}.width('100%').backgroundColor('#ffffff').border({ width: { top: 0.5 }, color: '#e0e0e0' })
}
}
设计理念:
@Component struct BorderRadiusExample {
build() {
Row({ space: 20 }) {
// 无圆角 - 方形设计
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 0, color: '#4CAF50' })
// 小圆角 - 轻微圆润
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 8, color: '#2196F3' })
// 完全圆形 - 圆角值为尺寸的一半
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 25, color: '#FF9800' })
// 不规则圆角 - 个性化设计
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: { topLeft: 0, topRight: 15, bottomLeft: 15, bottomRight: 0 }, color: '#9C27B0' })
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
}
interface UserInfo {
name: string
avatar: string
status: 'online' | 'busy' | 'offline'
}
@Component struct UserAvatarDemo {
private users: UserInfo[] = [
{ name: '张三', avatar: IconName.PERSON, status: 'online' },
{ name: '李四', avatar: IconName.PERSON, status: 'busy' },
{ name: '王五', avatar: IconName.PERSON, status: 'offline' }
]
build() {
Row({ space: 16 }) {
ForEach(this.users, (user: UserInfo) => {
Stack({ alignContent: Alignment.BottomEnd }) {
// 圆形头像容器
RcIcon({ name: user.avatar, iconSize: 56, iconRadius: 28, // 完全圆形 color: '#2196F3' })
// 状态指示器
Circle({ width: 14, height: 14 }).fill(this.getStatusColor(user.status)).stroke('#ffffff').strokeWidth(2).offset({ x: 2, y: 2 })
}.width(56).height(56)
})
}.width('100%').justifyContent(FlexAlign.Start).padding(20)
}
// 获取状态颜色
private getStatusColor(status: string): string {
const colorMap = {
'online': '#4CAF50', // 在线 - 绿色
'busy': '#ff9800', // 忙碌 - 橙色
'offline': '#9e9e9e' // 离线 - 灰色
}
return colorMap[status] || colorMap['offline']
}
}
实战技巧: 圆形头像 iconRadius 设置为 iconSize / 2,实现完美圆形效果。
RcIcon 不仅支持字体符号,还支持图片资源渲染:
@Component struct ImageResourceExample {
build() {
Row({ space: 20 }) {
// 基础图片渲染
RcIcon({ name: $r('app.media.startIcon'), iconSize: 40, iconRadius: 8 })
// 带颜色遮罩的图片 (仅对 SVG 生效)
RcIcon({ name: $r('app.media.startIcon'), iconSize: 50, iconRadius: 25, color: '#ff0000' // 对 PNG/JPG 无效,对 SVG 有效 })
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
}
@Component struct MixedMediaDemo {
build() {
Column({ space: 20 }) {
Text('商品分类').fontSize(18).fontWeight(FontWeight.Bold)
Grid() {
// 使用字体符号的分类
GridItem() {
this.CategoryCard(IconName.HOME_OUTLINE, '家居用品', true)
}
GridItem() {
this.CategoryCard(IconName.CAMERA_OUTLINE, '数码产品', true)
}
// 使用图片资源的分类
GridItem() {
this.CategoryCard($r('app.media.startIcon'), '精选商品', false)
}
GridItem() {
this.CategoryCard($r('app.media.startIcon'), '热门推荐', false)
}
}.columnsTemplate('1fr 1fr').rowsGap(16).columnsGap(16)
}.width('100%').padding(20)
}
@Builder CategoryCard(symbol: any, title: string, isFontSymbol: boolean) {
Column({ space: 12 }) {
RcIcon({ name: symbol, iconSize: 48, iconRadius: isFontSymbol ? 8 : 24, color: isFontSymbol ? '#2196F3' : undefined })
Text(title).fontSize(14).fontColor('#333333')
}.width('100%').height(120).backgroundColor('#f5f5f5').borderRadius(8).justifyContent(FlexAlign.Center)
}
}
注意事项:
color 属性仅对字体符号和 SVG 图片生效@Component struct ClickInteractionExample {
@State isFavorite: boolean = false
@State isBookmarked: boolean = false
build() {
Row({ space: 30 }) {
// 收藏功能
Column({ space: 8 }) {
RcIcon({
name: this.isFavorite ? IconName.HEART : IconName.HEART_OUTLINE,
iconSize: 40,
color: this.isFavorite ? '#ff0000' : '#999999',
onIconClick: () => {
this.isFavorite = !this.isFavorite
console.log('收藏状态:', this.isFavorite)
}
})
Text(this.isFavorite ? '已收藏' : '未收藏').fontSize(12).fontColor('#666666')
}
// 书签功能
Column({ space: 8 }) {
RcIcon({
name: this.isBookmarked ? IconName.BOOKMARK : IconName.BOOKMARK_OUTLINE,
iconSize: 40,
color: this.isBookmarked ? '#ffa500' : '#999999',
onIconClick: () => {
this.isBookmarked = !this.isBookmarked
console.log('书签状态:', this.isBookmarked)
}
})
Text(this.isBookmarked ? '已标记' : '未标记').fontSize(12).fontColor('#666666')
}
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
}
interface PostData {
id: string
content: string
likeCount: number
isLiked: boolean
commentCount: number
shareCount: number
}
@Component struct SocialInteractionDemo {
@State post: PostData = {
id: '001',
content: '这是一条精彩的动态内容...',
likeCount: 128,
isLiked: false,
commentCount: 45,
shareCount: 23
}
build() {
Column({ space: 16 }) {
// 动态内容
Text(this.post.content).fontSize(16).fontColor('#333333').padding(16).backgroundColor('#ffffff').borderRadius(8)
// 互动工具栏
Row({ space: 0 }) {
// 点赞
this.ActionButton(this.post.isLiked ? IconName.HEART : IconName.HEART_OUTLINE, this.post.likeCount.toString(), this.post.isLiked ? '#ff0000' : '#666666', () => this.handleLike())
// 评论
this.ActionButton(IconName.MESSAGE_CIRCLE_OUTLINE, this.post.commentCount.toString(), '#666666', () => this.handleComment())
// 分享
this.ActionButton(IconName.UPLOAD_OUTLINE, this.post.shareCount.toString(), '#666666', () => this.handleShare())
}.width('100%').height(48).backgroundColor('#ffffff').borderRadius(8)
}.width('100%').padding(20)
}
@Builder ActionButton(symbol: string, count: string, color: string, onClick: () => void) {
Row({ space: 6 }) {
RcIcon({ name: symbol, iconSize: 20, color: color, onIconClick: onClick })
Text(count).fontSize(14).fontColor(color)
}.width('33.33%').height('100%').justifyContent(FlexAlign.Center)
}
// 点赞处理
private handleLike() {
this.post.isLiked = !this.post.isLiked
this.post.likeCount += this.post.isLiked ? 1 : -1
console.log(`点赞状态:${this.post.isLiked}, 总数:${this.post.likeCount}`)
}
// 评论处理
private handleComment() {
console.log('打开评论面板')
}
// 分享处理
private handleShare() {
this.post.shareCount++
console.log('分享成功,总数:', this.post.shareCount)
}
}
交互设计要点:
根据功能对 492 个符号进行分类展示:
@Component struct IconLibraryDemo {
build() {
Scroll() {
Column({ space: 20 }) {
// 导航类符号
this.CategorySection('导航符号', [
{ name: IconName.HOME_OUTLINE, label: '首页' },
{ name: IconName.SEARCH_OUTLINE, label: '搜索' },
{ name: IconName.PERSON_OUTLINE, label: '我的' },
{ name: IconName.SETTINGS_OUTLINE, label: '设置' }
])
Divider()
// 操作类符号
this.CategorySection('操作符号', [
{ name: IconName.PLUS_OUTLINE, label: '添加' },
{ name: IconName.EDIT_OUTLINE, label: '编辑' },
{ name: IconName.TRASH_OUTLINE, label: '删除' },
{ name: IconName.SAVE_OUTLINE, label: '保存' }
])
Divider()
// 方向类符号
this.CategorySection('方向符号', [
{ name: IconName.ARROW_UP_OUTLINE, label: '向上' },
{ name: IconName.ARROW_DOWN_OUTLINE, label: '向下' },
{ name: IconName.ARROW_LEFT_OUTLINE, label: '向左' },
{ name: IconName.ARROW_RIGHT_OUTLINE, label: '向右' }
])
Divider()
// 状态类符号
this.CategorySection('状态符号', [
{ name: IconName.CHECKMARK_CIRCLE_OUTLINE, label: '成功', color: '#4CAF50' },
{ name: IconName.CLOSE_CIRCLE_OUTLINE, label: '失败', color: '#f44336' },
{ name: IconName.ALERT_CIRCLE_OUTLINE, label: '警告', color: '#ff9800' },
{ name: IconName.INFO_OUTLINE, label: '提示', color: '#2196F3' }
])
Divider()
// 通讯类符号
this.CategorySection('通讯符号', [
{ name: IconName.PHONE_OUTLINE, label: '电话' },
{ name: IconName.EMAIL_OUTLINE, label: '邮件' },
{ name: IconName.MESSAGE_CIRCLE_OUTLINE, label: '消息' },
{ name: IconName.BELL_OUTLINE, label: '通知' }
])
Divider()
// 文件类符号
this.CategorySection('文件符号', [
{ name: IconName.FILE_OUTLINE, label: '文件' },
{ name: IconName.FOLDER_OUTLINE, label: '文件夹' },
{ name: IconName.DOWNLOAD_OUTLINE, label: '下载' },
{ name: IconName.UPLOAD_OUTLINE, label: '上传' }
])
Divider()
// 媒体类符号
this.CategorySection('媒体符号', [
{ name: IconName.CAMERA_OUTLINE, label: '相机' },
{ name: IconName.IMAGE_OUTLINE, label: '图片' },
{ name: IconName.VIDEO_OUTLINE, label: '视频' },
{ name: IconName.MUSIC_OUTLINE, label: '音乐' }
])
Divider()
// 社交类符号
this.CategorySection('社交符号', [
{ name: IconName.GITHUB_OUTLINE, label: 'GitHub' },
{ name: IconName.TWITTER_OUTLINE, label: 'Twitter' },
{ name: IconName.FACEBOOK_OUTLINE, label: 'Facebook' },
{ name: IconName.LINKEDIN_OUTLINE, label: 'LinkedIn' }
])
// 底部间距
Text(' ').height(20)
}.width('100%').padding(20)
}.height('100%').backgroundColor('#f5f5f5')
}
// 分类区块构建器
@Builder CategorySection(title: string, items: Array<{ name: string, label: string, color?: string }>) {
Column({ space: 12 }) {
Text(title).fontSize(16).fontWeight(FontWeight.Bold).fontColor('#333333').width('100%')
Row({ space: 20 }) {
ForEach(items, (item: any) => {
this.SymbolWithLabel(item.name, item.label, item.color || '#333333')
})
}.width('100%')
}
}
// 带标签的符号组件
@Builder SymbolWithLabel(symbolName: string, label: string, color: string) {
Column({ space: 6 }) {
RcIcon({ name: symbolName, iconSize: 28, color: color })
Text(label).fontSize(11).fontColor('#666666').textAlign(TextAlign.Center)
}.width(70)
}
}
组织策略:
@Component struct AnimationExample {
@State rotation: number = 0
build() {
Row({ space: 30 }) {
// 同步符号动画
Column({ space: 8 }) {
RcIcon({
name: IconName.SYNC,
iconSize: 40,
color: '#2196F3',
iconAnimation: { duration: 1000, curve: Curve.Linear, iterations: -1 // 无限循环 },
onIconClick: () => {
console.log('同步符号被点击')
}
}).rotate({ angle: this.rotation })
Text('同步中').fontSize(12).fontColor('#666666')
}
// 加载符号动画
Column({ space: 8 }) {
RcIcon({
name: IconName.LOADER_OUTLINE,
iconSize: 40,
color: '#FF9800',
iconAnimation: { duration: 800, curve: Curve.EaseInOut, iterations: -1 // 无限循环 }
}).rotate({ angle: this.rotation })
Text('加载中').fontSize(12).fontColor('#666666')
}
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).padding(20)
}
aboutToAppear(): void {
// 启动旋转动画
this.startRotation()
}
// 旋转动画循环
startRotation() {
setInterval(() => {
this.rotation = (this.rotation + 10) % 360
}, 16) // 约 60fps
}
}
enum LoadingState {
IDLE = 'idle',
LOADING = 'loading',
SUCCESS = 'success',
ERROR = 'error'
}
@Component struct LoadingIndicatorDemo {
@State loadingState: LoadingState = LoadingState.IDLE
@State rotation: number = 0
private rotationTimer: number = -1
build() {
Column({ space: 24 }) {
// 加载状态展示
Column({ space: 16 }) {
if (this.loadingState === LoadingState.LOADING) {
RcIcon({
name: IconName.LOADER_OUTLINE,
iconSize: 48,
color: '#2196F3',
iconAnimation: { duration: 1000, curve: Curve.Linear, iterations: -1 }
}).rotate({ angle: this.rotation })
Text('数据加载中...').fontSize(14).fontColor('#666666')
} else if (this.loadingState === LoadingState.SUCCESS) {
RcIcon({ name: IconName.CHECKMARK_CIRCLE_OUTLINE, iconSize: 48, color: '#4CAF50' })
Text('加载成功').fontSize(14).fontColor('#4CAF50')
} else if (this.loadingState === LoadingState.ERROR) {
RcIcon({ name: IconName.CLOSE_CIRCLE_OUTLINE, iconSize: 48, color: '#f44336' })
Text('加载失败').fontSize(14).fontColor('#f44336')
} else {
RcIcon({ name: IconName.INFO_OUTLINE, iconSize: 48, color: '#999999' })
Text('点击按钮开始加载').fontSize(14).fontColor('#999999')
}
}.width('100%').height(120).justifyContent(FlexAlign.Center).backgroundColor('#f5f5f5').borderRadius(8)
// 操作按钮
Row({ space: 12 }) {
Button('开始加载').onClick(() => this.simulateLoading()).backgroundColor('#2196F3')
Button('重置').onClick(() => this.reset()).backgroundColor('#999999')
}
}.width('100%').padding(20)
}
aboutToAppear(): void {
this.startRotation()
}
aboutToDisappear(): void {
if (this.rotationTimer !== -1) {
clearInterval(this.rotationTimer)
}
}
// 启动旋转动画
private startRotation() {
this.rotationTimer = setInterval(() => {
if (this.loadingState === LoadingState.LOADING) {
this.rotation = (this.rotation + 10) % 360
}
}, 16)
}
// 模拟加载过程
private simulateLoading() {
this.loadingState = LoadingState.LOADING
// 模拟 2 秒后加载完成
setTimeout(() => {
// 50% 概率成功/失败
this.loadingState = Math.random() > 0.5 ? LoadingState.SUCCESS : LoadingState.ERROR
}, 2000)
}
// 重置状态
private reset() {
this.loadingState = LoadingState.IDLE
this.rotation = 0
}
}
动画最佳实践:
以下是基于原始案例集的完整实现代码:
import { RcIcon, IconName } from "rchoui"
@Entry
@Component struct RcIconDemo {
@State isFavorite: boolean = false
@State isBookmarked: boolean = false
@State rotation: number = 0
build() {
Scroll() {
Column({ space: 30 }) {
// 基础用法
this.SectionTitle('基础用法')
Row({ space: 20 }) {
RcIcon({ name: IconName.HOME })
RcIcon({ name: IconName.HEART_OUTLINE })
RcIcon({ name: IconName.STAR })
RcIcon({ name: 'icon-houi_search' })
}
Divider()
// 不同尺寸
this.SectionTitle('不同尺寸')
Row({ space: 20 }) {
RcIcon({ name: IconName.SETTINGS, iconSize: 16 })
RcIcon({ name: IconName.SETTINGS, iconSize: 24 })
RcIcon({ name: IconName.SETTINGS, iconSize: 32 })
RcIcon({ name: IconName.SETTINGS, iconSize: 48 })
RcIcon({ name: IconName.SETTINGS, iconSize: '64vp' })
}
Divider()
// 不同颜色
this.SectionTitle('不同颜色')
Row({ space: 20 }) {
RcIcon({ name: IconName.HEART, color: '#ff0000', iconSize: 32 })
RcIcon({ name: IconName.HEART, color: Color.Blue, iconSize: 32 })
RcIcon({ name: IconName.HEART, color: '#ff6b6b', iconSize: 32 })
RcIcon({ name: IconName.HEART, color: '#00d4ff', iconSize: 32 })
RcIcon({ name: IconName.HEART, color: '#ffa500', iconSize: 32 })
}
Divider()
// 线型与实底风格
this.SectionTitle('线型与实底风格')
Column({ space: 15 }) {
Row({ space: 20 }) {
Text('线型:').fontSize(14).width(60)
RcIcon({ name: IconName.HOME_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.HEART_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.STAR_OUTLINE, iconSize: 28 })
RcIcon({ name: IconName.PERSON_OUTLINE, iconSize: 28 })
}
Row({ space: 20 }) {
Text('实底:').fontSize(14).width(60)
RcIcon({ name: IconName.HOME, iconSize: 28 })
RcIcon({ name: IconName.HEART, iconSize: 28 })
RcIcon({ name: IconName.STAR, iconSize: 28 })
RcIcon({ name: IconName.PERSON, iconSize: 28 })
}
}
Divider()
// 圆角设置
this.SectionTitle('圆角设置')
Row({ space: 20 }) {
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 0, color: '#4CAF50' })
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 8, color: '#2196F3' })
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: 25, color: '#FF9800' })
RcIcon({ name: IconName.IMAGE, iconSize: 50, iconRadius: { topLeft: 0, topRight: 15, bottomLeft: 15, bottomRight: 0 }, color: '#9C27B0' })
}
Divider()
// 使用图片资源
this.SectionTitle('使用图片资源')
Row({ space: 20 }) {
RcIcon({ name: $r('app.media.startIcon'), iconSize: 40, iconRadius: 8 })
RcIcon({ name: $r('app.media.startIcon'), iconSize: 50, iconRadius: 25, color: '#ff0000' })
}
Divider()
// 点击交互
this.SectionTitle('点击交互')
Row({ space: 30 }) {
Column({ space: 8 }) {
RcIcon({
name: this.isFavorite ? IconName.HEART : IconName.HEART_OUTLINE,
iconSize: 40,
color: this.isFavorite ? '#ff0000' : '#999999',
onIconClick: () => {
this.isFavorite = !this.isFavorite
console.log('收藏状态:', this.isFavorite)
}
})
Text(this.isFavorite ? '已收藏' : '未收藏').fontSize(12).fontColor('#666666')
}
Column({ space: 8 }) {
RcIcon({
name: this.isBookmarked ? IconName.BOOKMARK : IconName.BOOKMARK_OUTLINE,
iconSize: 40,
color: this.isBookmarked ? '#ffa500' : '#999999',
onIconClick: () => {
this.isBookmarked = !this.isBookmarked
console.log('书签状态:', this.isBookmarked)
}
})
Text(this.isBookmarked ? '已标记' : '未标记').fontSize(12).fontColor('#666666')
}
}
Divider()
// 常用符号展示
this.SectionTitle('常用符号')
Column({ space: 20 }) {
// 导航符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.HOME_OUTLINE, '首页')
this.SymbolWithLabel(IconName.SEARCH_OUTLINE, '搜索')
this.SymbolWithLabel(IconName.PERSON_OUTLINE, '我的')
this.SymbolWithLabel(IconName.SETTINGS_OUTLINE, '设置')
}
// 操作符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.PLUS_OUTLINE, '添加')
this.SymbolWithLabel(IconName.EDIT_OUTLINE, '编辑')
this.SymbolWithLabel(IconName.TRASH_OUTLINE, '删除')
this.SymbolWithLabel(IconName.SAVE_OUTLINE, '保存')
}
// 箭头符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.ARROW_UP_OUTLINE, '向上')
this.SymbolWithLabel(IconName.ARROW_DOWN_OUTLINE, '向下')
this.SymbolWithLabel(IconName.ARROW_LEFT_OUTLINE, '向左')
this.SymbolWithLabel(IconName.ARROW_RIGHT_OUTLINE, '向右')
}
// 状态符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.CHECKMARK_CIRCLE_OUTLINE, '成功', '#4CAF50')
this.SymbolWithLabel(IconName.CLOSE_CIRCLE_OUTLINE, '失败', '#f44336')
this.SymbolWithLabel(IconName.ALERT_CIRCLE_OUTLINE, '警告', '#ff9800')
this.SymbolWithLabel(IconName.INFO_OUTLINE, '提示', '#2196F3')
}
// 通讯符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.PHONE_OUTLINE, '电话')
this.SymbolWithLabel(IconName.EMAIL_OUTLINE, '邮件')
this.SymbolWithLabel(IconName.MESSAGE_CIRCLE_OUTLINE, '消息')
this.SymbolWithLabel(IconName.BELL_OUTLINE, '通知')
}
// 文件符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.FILE_OUTLINE, '文件')
this.SymbolWithLabel(IconName.FOLDER_OUTLINE, '文件夹')
this.SymbolWithLabel(IconName.DOWNLOAD_OUTLINE, '下载')
this.SymbolWithLabel(IconName.UPLOAD_OUTLINE, '上传')
}
// 媒体符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.CAMERA_OUTLINE, '相机')
this.SymbolWithLabel(IconName.IMAGE_OUTLINE, '图片')
this.SymbolWithLabel(IconName.VIDEO_OUTLINE, '视频')
this.SymbolWithLabel(IconName.MUSIC_OUTLINE, '音乐')
}
// 社交符号
Row({ space: 20 }) {
this.SymbolWithLabel(IconName.GITHUB_OUTLINE, 'GitHub')
this.SymbolWithLabel(IconName.TWITTER_OUTLINE, 'Twitter')
this.SymbolWithLabel(IconName.FACEBOOK_OUTLINE, 'Facebook')
this.SymbolWithLabel(IconName.LINKEDIN_OUTLINE, 'LinkedIn')
}
}
Divider()
// 动画效果
this.SectionTitle('动画效果')
Row({ space: 30 }) {
Column({ space: 8 }) {
RcIcon({
name: IconName.SYNC,
iconSize: 40,
color: '#2196F3',
iconAnimation: { duration: 1000, curve: Curve.Linear, iterations: -1 },
onIconClick: () => {
console.log('同步符号被点击')
}
}).rotate({ angle: this.rotation })
Text('同步中').fontSize(12).fontColor('#666666')
}
Column({ space: 8 }) {
RcIcon({
name: IconName.LOADER_OUTLINE,
iconSize: 40,
color: '#FF9800',
iconAnimation: { duration: 800, curve: Curve.EaseInOut, iterations: -1 }
}).rotate({ angle: this.rotation })
Text('加载中').fontSize(12).fontColor('#666666')
}
}
// 底部间距
Text(' ').height(20)
}.width('100%').padding(20)
}.height('100%').width('100%').backgroundColor('#f5f5f5')
}
aboutToAppear(): void {
// 启动旋转动画
this.startRotation()
}
// 旋转动画
startRotation() {
setInterval(() => {
this.rotation = (this.rotation + 10) % 360
}, 16)
}
// 章节标题组件
@Builder SectionTitle(title: string) {
Text(title).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#333333').width('100%').margin({ top: 10, bottom: 10 })
}
// 带标签的符号组件
@Builder SymbolWithLabel(symbolName: string, label: string, color: string = '#333333') {
Column({ space: 6 }) {
RcIcon({ name: symbolName, iconSize: 28, color: color })
Text(label).fontSize(11).fontColor('#666666').textAlign(TextAlign.Center)
}.width(70)
}
}
| 特性维度 | 展示内容 | 实战价值 |
|---|---|---|
| 基础用法 | 三种引用方式 | 掌握组件基本使用方法 |
| 尺寸系统 | 5 个尺寸级别 | 建立统一的尺寸规范 |
| 颜色系统 | 多种颜色设置方式 | 实现丰富的视觉表达 |
| 双风格系统 | 线型/实底对比 | 实现状态切换效果 |
| 圆角系统 | 4 种圆角配置 | 打造个性化视觉风格 |
| 资源支持 | 字体符号 + 图片资源 | 混合使用多种素材类型 |
| 点击交互 | 收藏/书签功能 | 实现用户交互反馈 |
| 符号分类 | 8 大类 32 个常用符号 | 快速查找所需符号 |
| 动画效果 | 旋转加载动画 | 提升用户体验 |
// ✅ 推荐:使用 IconName 常量
RcIcon({ name: IconName.HOME })
// ❌ 不推荐:直接使用字符串 (容易拼写错误)
RcIcon({ name: 'icon-houi_hom' }) // 拼写错误
// ✅ 推荐:建立尺寸规范
enum IconSize {
SM = 16,
MD = 24,
LG = 32
}
RcIcon({ name: IconName.HOME, iconSize: IconSize.MD })
// ❌ 不推荐:随意设置尺寸
RcIcon({ name: IconName.HOME, iconSize: 23 }) // 不符合规范
// ✅ 推荐:合理使用颜色变量
const PRIMARY_COLOR = '#2196F3'
RcIcon({ name: IconName.HOME, color: PRIMARY_COLOR })
// ❌ 不推荐:硬编码颜色值
RcIcon({ name: IconName.HOME, color: '#2196f3' }) // 不易维护
@Component struct PerformanceOptimizedDemo {
// ✅ 推荐:缓存符号配置
private readonly SYMBOL_CONFIG = { size: 24, color: '#333333' }
// ✅ 推荐:使用 @Builder 避免重复创建
@Builder CommonSymbol(name: string) {
RcIcon({ name: name, iconSize: this.SYMBOL_CONFIG.size, color: this.SYMBOL_CONFIG.color })
}
build() {
Column() {
// 使用缓存的配置
ForEach(['HOME', 'SEARCH', 'PERSON'], (item: string) => {
this.CommonSymbol(IconName[item])
})
}
}
}
// ❌ 不推荐:在循环中创建大量组件实例
@Component struct NonOptimizedDemo {
build() {
Column() {
ForEach(Array.from({ length: 1000 }), () => {
RcIcon({ name: IconName.HOME, iconSize: 24, color: '#333333' })
})
}
}
}
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 符号不显示 | 字体未注册或名称错误 | 检查 IconName 常量是否正确 |
| 颜色不生效 | 使用了图片资源 | 图片资源不支持 color 属性 |
| 动画卡顿 | 刷新频率过高 | 使用 16ms 间隔 (60fps) |
| 内存泄漏 | 定时器未清理 | 在 aboutToDisappear 中清理 |
| 点击无响应 | 热区太小 | 增大触摸区域或使用 padding |
RcIcon 组件通过 字体符号技术 + 类型安全系统 + 灵活的属性配置,为 HarmonyOS6 应用开发提供了强大的视觉表达能力:
✅ 492 个精心设计的符号: 涵盖 8 大应用场景
✅ 双风格系统: 线型/实底自由切换
✅ 完善的类型系统: IconName 常量提供 IDE 支持
✅ 灵活的样式定制: 尺寸、颜色、圆角全面可控
✅ 图片资源兼容: 支持字体符号和图片混合使用
✅ 丰富的交互能力: 点击事件、动画效果
通过本文档的 10 个实战案例,开发者可以:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online