HarmonyOS6半年磨一剑 - RcIcon组件实战案例集与应用开发指南

HarmonyOS6半年磨一剑 - RcIcon组件实战案例集与应用开发指南

文章目录

前言

各位开发者,大家好!我是若城。

在鸿蒙应用开发过程中,我发现许多组件样式和工具方法具有高度的复用性,但每次新项目都需要重复编写,这极大地降低了开发效率。因此,我决定投入半年时间,打造一款专为鸿蒙生态设计的 UI 组件库 —— rchoui

项目简介

rchoui 是一个面向 HarmonyOS6 的企业级 UI 组件库,旨在提供开箱即用的高质量组件,让开发者告别"重复造轮子"。

核心特性

  • 丰富组件:涵盖基础组件、表单组件、弹窗组件、布局组件等
  • 设计规范:遵循统一的色彩体系和设计语言
  • 工具集成:内置常用工具方法,提升开发效率
  • 完善文档:每个模块都配有详细的设计思路和使用说明

开源计划

项目预计于 2026 年 7 月中旬正式开源,届时可通过三方库直接下载使用。在此期间,我会通过系列文章逐一介绍每个模块的设计思路与实现细节。

rchoui官网

目前暂定 rchoui 官网地址:http://rchoui.ruocheng.site/

需要注意的是 当前官网还在完善当中, 会在后续更新中逐步完善。届时可以为大家提供更加完善的说明文档

文档概述

本文档基于 RcIcon 组件的完整实战案例集,通过 10 个典型应用场景,展示如何在真实项目中灵活运用字体符号组件。每个案例都包含完整的代码实现、效果说明和最佳实践建议,帮助开发者快速掌握 RcIcon 组件的实战技巧。

适用读者: HarmonyOS6 应用开发者、UI/UX 工程师、前端架构师

核心内容:

  • 10 个真实业务场景的完整实现
  • 从基础用法到高级交互的渐进式教学
  • 涵盖尺寸、颜色、动画、点击交互等所有特性
  • 提供可直接运行的完整示例代码
  • 包含最佳实践和性能优化建议

第一章: 基础用法实战

1.1 三种符号引用方式

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 自动补全和类型检查,避免拼写错误
  • 线型与实底成对使用: HOMEHOME_OUTLINE 配合使用,满足激活/未激活状态切换
  • 字符串方式作为补充: 当需要动态拼接符号名称时使用

1.2 应用场景 - 工具栏快速导航

@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 个常用功能的工具栏,代码简洁且易于维护。


第二章: 尺寸系统实战

2.1 响应式尺寸配置

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)}}

2.2 应用场景 - 统一设计系统尺寸规范

建立符号尺寸规范体系,确保整个应用的视觉一致性:

// 定义符号尺寸规范枚举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)}}

最佳实践:

  • ✅ 建立统一的尺寸规范枚举,避免随意设置尺寸
  • ✅ 触摸区域至少 44×44 vp,小符号需增加点击热区
  • ✅ 相同层级的符号使用相同尺寸,保持视觉平衡

第三章: 颜色系统实战

3.1 多彩色系配置

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)}}

3.2 应用场景 - 状态指示系统

通过颜色快速传递系统状态信息:

// 定义状态颜色规范classStatusColors{staticreadonlySUCCESS='#4CAF50'// 成功 - 绿色staticreadonlyERROR='#f44336'// 错误 - 红色staticreadonlyWARNING='#ff9800'// 警告 - 橙色staticreadonlyINFO='#2196F3'// 信息 - 蓝色staticreadonlyDEFAULT='#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)}// 根据状态返回对应符号privategetStatusSymbol():string{const symbolMap ={'pending': IconName.INFO_OUTLINE,'success': IconName.CHECKMARK_CIRCLE_OUTLINE,'failed': IconName.CLOSE_CIRCLE_OUTLINE}return symbolMap[this.orderStatus]}// 根据状态返回对应颜色privategetStatusColor():string{const colorMap ={'pending': StatusColors.INFO,'success': StatusColors.SUCCESS,'failed': StatusColors.ERROR}return colorMap[this.orderStatus]}// 根据状态返回对应文本privategetStatusText():string{const textMap ={'pending':'订单处理中','success':'订单已完成','failed':'订单已失败'}return textMap[this.orderStatus]}}

实战价值: 通过颜色和符号的组合,用户可以在 0.3 秒内识别系统状态,提升信息传达效率。


第四章: 双风格系统实战

4.1 线型与实底风格对比

@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)}}

4.2 应用场景 - 底部导航栏

通过线型/实底风格切换实现标签页激活状态:

interfaceTabItem{ symbolOutline:string symbolFilled:string label:string}@Component struct BottomTabBarDemo {@State activeTab:number=0private 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'})}}

设计理念:

  • ✅ 未选中状态使用线型风格,视觉轻量不抢眼
  • ✅ 选中状态使用实底风格 + 主题色,突出当前位置
  • ✅ 风格切换提供明确的视觉反馈,增强可用性

第五章: 圆角系统实战

5.1 多样化圆角配置

@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)}}

5.2 应用场景 - 用户头像系统

interfaceUserInfo{ 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)}// 获取状态颜色privategetStatusColor(status:string):string{const colorMap ={'online':'#4CAF50',// 在线 - 绿色'busy':'#ff9800',// 忙碌 - 橙色'offline':'#9e9e9e'// 离线 - 灰色}return colorMap[status]|| colorMap['offline']}}

实战技巧: 圆形头像 iconRadius 设置为 iconSize / 2,实现完美圆形效果。


第六章: 图片资源实战

6.1 图片资源渲染

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)}}

6.2 应用场景 - 混合素材展示

@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)}@BuilderCategoryCard(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 图片生效
  • ⚠️ PNG/JPG 等位图格式不支持颜色遮罩
  • ✅ 推荐使用字体符号以获得更好的灵活性

第七章: 点击交互实战

7.1 基础点击事件

@Component struct ClickInteractionExample {@State isFavorite:boolean=false@State isBookmarked:boolean=falsebuild(){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)}}

7.2 应用场景 - 社交互动系统

interfacePostData{ 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)}@BuilderActionButton(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)}// 点赞处理privatehandleLike(){this.post.isLiked =!this.post.isLiked this.post.likeCount +=this.post.isLiked ?1:-1console.log(`点赞状态: ${this.post.isLiked}, 总数: ${this.post.likeCount}`)}// 评论处理privatehandleComment(){console.log('打开评论面板')}// 分享处理privatehandleShare(){this.post.shareCount++console.log('分享成功,总数:',this.post.shareCount)}}

交互设计要点:

  • ✅ 点击后立即提供视觉反馈(颜色/形状变化)
  • ✅ 配合数值变化增强真实感
  • ✅ 合理使用线型/实底切换表达状态

第八章: 符号分类展示实战

8.1 符号库完整展示

根据功能对 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')}// 分类区块构建器@BuilderCategorySection(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%')}}// 带标签的符号组件@BuilderSymbolWithLabel(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)}}

组织策略:

  • ✅ 按功能维度分类,便于查找使用
  • ✅ 状态类符号使用对应语义颜色
  • ✅ 统一尺寸和间距,保持视觉协调

第九章: 动画效果实战

9.1 旋转动画实现

@Component struct AnimationExample {@State rotation:number=0build(){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}}

9.2 应用场景 - 加载状态指示器

enum LoadingState {IDLE='idle',LOADING='loading',SUCCESS='success',ERROR='error'}@Component struct LoadingIndicatorDemo {@State loadingState: LoadingState = LoadingState.IDLE@State rotation:number=0private rotationTimer:number=-1build(){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')}elseif(this.loadingState === LoadingState.SUCCESS){RcIcon({ name: IconName.CHECKMARK_CIRCLE_OUTLINE, iconSize:48, color:'#4CAF50'})Text('加载成功').fontSize(14).fontColor('#4CAF50')}elseif(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)}}// 启动旋转动画privatestartRotation(){this.rotationTimer =setInterval(()=>{if(this.loadingState === LoadingState.LOADING){this.rotation =(this.rotation +10)%360}},16)}// 模拟加载过程privatesimulateLoading(){this.loadingState = LoadingState.LOADING// 模拟 2 秒后加载完成setTimeout(()=>{// 50% 概率成功/失败this.loadingState = Math.random()>0.5? LoadingState.SUCCESS: LoadingState.ERROR},2000)}// 重置状态privatereset(){this.loadingState = LoadingState.IDLEthis.rotation =0}}

动画最佳实践:

  • ✅ 使用 60fps (16ms 间隔) 确保流畅度
  • ✅ 加载完成后停止动画,避免资源浪费
  • ✅ 组件销毁时清理定时器,防止内存泄漏

第十章: 完整实战案例 - 符号展示系统

10.1 完整代码实现

以下是基于原始案例集的完整实现代码:

import{ RcIcon, IconName }from"rchoui"@Entry@Component struct RcIconDemo {@State isFavorite:boolean=false@State isBookmarked:boolean=false@State rotation:number=0build(){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)}// 章节标题组件@BuilderSectionTitle(title:string){Text(title).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#333333').width('100%').margin({ top:10, bottom:10})}// 带标签的符号组件@BuilderSymbolWithLabel(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)}}

10.2 案例特点总结

特性维度展示内容实战价值
基础用法三种引用方式掌握组件基本使用方法
尺寸系统5 个尺寸级别建立统一的尺寸规范
颜色系统多种颜色设置方式实现丰富的视觉表达
双风格系统线型/实底对比实现状态切换效果
圆角系统4 种圆角配置打造个性化视觉风格
资源支持字体符号+图片资源混合使用多种素材类型
点击交互收藏/书签功能实现用户交互反馈
符号分类8 大类 32 个常用符号快速查找所需符号
动画效果旋转加载动画提升用户体验

第十一章: 最佳实践与性能优化

11.1 开发最佳实践

// ✅ 推荐: 使用 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})// 不符合规范// ✅ 推荐: 合理使用颜色变量constPRIMARY_COLOR='#2196F3'RcIcon({ name: IconName.HOME, color:PRIMARY_COLOR})// ❌ 不推荐: 硬编码颜色值RcIcon({ name: IconName.HOME, color:'#2196f3'})// 不易维护

11.2 性能优化建议

@Component struct PerformanceOptimizedDemo {// ✅ 推荐: 缓存符号配置privatereadonlySYMBOL_CONFIG={ size:24, color:'#333333'}// ✅ 推荐: 使用 @Builder 避免重复创建@BuilderCommonSymbol(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'})})}}}

11.3 常见问题解决

问题原因解决方案
符号不显示字体未注册或名称错误检查 IconName 常量是否正确
颜色不生效使用了图片资源图片资源不支持 color 属性
动画卡顿刷新频率过高使用 16ms 间隔(60fps)
内存泄漏定时器未清理aboutToDisappear 中清理
点击无响应热区太小增大触摸区域或使用 padding

第十二章: 总结

12.1 核心能力总结

RcIcon 组件通过 字体符号技术 + 类型安全系统 + 灵活的属性配置,为 HarmonyOS6 应用开发提供了强大的视觉表达能力:

492 个精心设计的符号: 涵盖 8 大应用场景
双风格系统: 线型/实底自由切换
完善的类型系统: IconName 常量提供 IDE 支持
灵活的样式定制: 尺寸、颜色、圆角全面可控
图片资源兼容: 支持字体符号和图片混合使用
丰富的交互能力: 点击事件、动画效果

12.2 实战价值

通过本文档的 10 个实战案例,开发者可以:

  1. 快速上手: 15 分钟掌握基础用法
  2. 建立规范: 构建统一的符号使用标准
  3. 提升效率: 减少 70% 的符号资源管理工作
  4. 增强体验: 通过动画和交互提升用户满意度
  5. 降低成本: 字体符号相比图片资源体积减少 90%
Could not load content