一、属性系统概览
RcIcon 组件提供了 7 个核心属性,覆盖了符号显示的所有关键维度:
| 属性 | 类型 | 默认值 | 描述 |
|---|
name | `keyof RcIconDataType | ResourceStr` | 必需 |
color | ResourceColor | undefined | 符号颜色 |
iconSize | RcStringNumber | baseStyle.fontSizeLg | 符号大小 |
iconRadius | `Length | BorderRadiuses` | 0 |
fontName | ResourceStr | "" | 自定义字体名称 |
iconAnimation | AnimateParam | undefined | 动画参数 |
onIconClick | (event: TouchEvent) => void | () => {} | 点击事件回调 |
二、name 属性详解
2.1 属性定义
类型说明:
keyof RcIconDataType:492 个预定义符号名称
ResourceStr:HarmonyOS 资源引用类型
@Require:必需参数,不可省略
2.2 使用方式
方式 1:使用 IconName 常量(推荐)
import { RcIcon, IconName } from 'rchoui';
RcIcon({ name: IconName.HOME });
RcIcon({ name: IconName.HOME_OUTLINE });
方式 2:使用字符串字面量
RcIcon({ name: 'icon-houi_home' });
RcIcon({ name: 'icon-houi_home_outline' });
方式 3:使用本地资源
RcIcon({ name: $r('app.media.logo') });
RcIcon({ name: $rawfile('custom.png') });
方式 4:使用在线图片
RcIcon({ name: 'https://example.com/image.png' });
RcIcon({ name: 'http://cdn.com/icon.svg' });
方式 5:直接使用 Unicode
RcIcon({ name: '\ue7c7' });
2.3 资源类型识别
组件内部通过以下逻辑识别资源类型:
if (typeof this.name === "string") {
if (this.name.startsWith("http")) {
return <Image>;
} else {
return <Text>;
}
} else {
return <Image>;
}
三、color 属性详解
3.1 属性定义
类型说明:
ResourceColor:HarmonyOS 标准颜色类型
- 可选参数,默认
undefined(继承父组件)
3.2 颜色值支持
十六进制颜色
RcIcon({ name: IconName.HEART, color: '#ff0000' });
RcIcon({ name: IconName.HEART, color: '#f00' });
RGB/RGBA 颜色
RcIcon({ name: IconName.STAR, color: 'rgb(255, 165, 0)' });
RcIcon({ name: IconName.STAR, color: 'rgba(255, 165, 0, 0.8)' });
命名颜色
RcIcon({ name: IconName.INFO, color: Color.Blue });
RcIcon({ name: IconName.SUCCESS, color: Color.Green });
资源颜色
RcIcon({ name: IconName.PRIMARY, color: $r('app.color.primary') });
RcIcon({ name: IconName.BRAND, color: $r('sys.color.brand') });
3.3 颜色应用机制
字体符号颜色:
Text(this.getIconContent()).fontColor(this.color);
图片符号颜色:
Image(this.name).fillColor(this.color);
注意事项:
- PNG/JPG 图片不支持
fillColor,会被忽略
- SVG 图片支持
fillColor,可改变填充色
- 字体符号完全支持任意颜色
3.4 颜色使用场景
状态表达
@State isActive: boolean = false;
RcIcon({ name: IconName.STAR, color: this.isActive ? '#ffaa00' : '#cccccc' });
语义化颜色
RcIcon({ name: IconName.CHECKMARK_CIRCLE, color: '#52c41a' });
RcIcon({ name: IconName.CLOSE_CIRCLE, color: '#ff4d4f' });
RcIcon({ name: IconName.ALERT_TRIANGLE, color: '#faad14' });
RcIcon({ name: IconName.INFO, color: '#1890ff' });
主题色适配
RcIcon({ name: IconName.HOME, color: $r('app.color.primary') });
RcIcon({ name: IconName.MOON, color: this.isDarkMode ? '#ffffff' : '#000000' });
四、iconSize 属性详解
4.1 属性定义
type RcStringNumber = string | number;
默认值:
- 从全局样式获取:
baseStyle.fontSizeLg
- 通常为 18-20vp
4.2 尺寸值格式
数字格式(自动添加 vp 单位)
RcIcon({ name: IconName.HOME, iconSize: 20 });
RcIcon({ name: IconName.HOME, iconSize: 30 });
RcIcon({ name: IconName.HOME, iconSize: 40 });
字符串格式(明确指定单位)
RcIcon({ name: IconName.HOME, iconSize: '20vp' });
RcIcon({ name: IconName.HOME, iconSize: '30px' });
RcIcon({ name: IconName.HOME, iconSize: '40lpx' });
RcIcon({ name: IconName.HOME, iconSize: '50fp' });
4.3 尺寸处理函数
function getSizeByUnit(size: RcStringNumber, isFontSize?: boolean): Length {
if (typeof size === 'number') {
return isFontSize ? `${size}fp` : `${size}vp`;
}
return size;
}
.fontSize(getSizeByUnit(this.iconSize, true));
.width(getSizeByUnit(this.iconSize));
.height(getSizeByUnit(this.iconSize));
4.4 标准尺寸规范
| 尺寸级别 | 推荐值 | 适用场景 |
|---|
| 超小 | 12-14 | 表格内符号、标签 |
| 小号 | 16-18 | 列表项符号、按钮前缀 |
| 常规 | 20-24 | 导航栏、工具栏 |
| 中等 | 28-32 | 卡片装饰、功能入口 |
| 大号 | 40-48 | 页面主体符号 |
| 超大 | 64+ | 空状态、引导页 |
4.5 响应式尺寸
@State windowWidth: number = 0;
aboutToAppear() {
this.windowWidth = display.getDefaultDisplaySync().width;
}
build() {
RcIcon({ name: IconName.HOME, iconSize: this.windowWidth < 600 ? 20 : 24 });
}
五、iconRadius 属性详解
5.1 属性定义
类型说明:
Length:单一圆角值
BorderRadiuses:四角独立设置
LocalizedBorderRadiuses:支持本地化的圆角
5.2 统一圆角
RcIcon({ name: IconName.HOME, iconRadius: 4 });
RcIcon({ name: IconName.HOME, iconRadius: 8 });
RcIcon({ name: IconName.HOME, iconRadius: '8vp' });
RcIcon({ name: IconName.HOME, iconRadius: '50%' });
5.3 独立圆角
RcIcon({
name: $r('app.media.avatar'),
iconSize: 40,
iconRadius: { topLeft: 4, topRight: 8, bottomLeft: 8, bottomRight: 4 }
});
5.4 圆形符号
RcIcon({ name: $r('app.media.avatar'), iconSize: 40, iconRadius: '50%' });
RcIcon({ name: $r('app.media.avatar'), iconSize: 40, iconRadius: 20 });
5.5 应用场景
头像符号
RcIcon({ name: $r('app.media.avatar'), iconSize: 50, iconRadius: '50%' });
品牌 Logo
RcIcon({ name: $r('app.media.brand'), iconSize: 60, iconRadius: 12 });
图片符号
RcIcon({ name: 'https://example.com/thumb.jpg', iconSize: 80, iconRadius: 8 });
六、fontName 属性详解
6.1 属性定义
用途:
- 指定自定义字体族名称
- 替代默认的
rcFont 字体
- 支持第三方字体库
6.2 使用场景
使用第三方字体
aboutToAppear() {
let font: Font = this.getUIContext().getFont();
font.registerFont({
familyName: 'MaterialIcons',
familySrc: $rawfile('MaterialIcons.ttf')
});
}
RcIcon({
name: '\ue88a',
fontName: 'MaterialIcons'
});
项目特定字体
RcIcon({ name: 'custom-symbol', fontName: $rawfile('ProjectFont.woff') });
6.3 注意事项
- 字体需要先注册:在使用前必须调用
registerFont()
- Unicode 对应:确保传入的 Unicode 存在于自定义字体中
- 资源路径:字体文件通常放在
rawfile 目录
- 性能考虑:避免注册过多字体,影响加载性能
七、iconAnimation 属性详解
7.1 属性定义
interface AnimateParam {
duration?: number;
curve?: Curve | ICurve;
delay?: number;
iterations?: number;
playMode?: PlayMode;
}
7.2 旋转动画
@State rotationAngle: number = 0;
RcIcon({
name: IconName.SYNC,
iconSize: 30,
iconAnimation: {
duration: 1000,
curve: Curve.Linear,
iterations: -1
}
}).rotate({ angle: this.rotationAngle }).onAppear(() => {
this.rotationAngle = 360;
});
7.3 缩放动画
@State scale: number = 1;
RcIcon({
name: IconName.HEART,
iconSize: 30,
iconAnimation: {
duration: 300,
curve: Curve.EaseInOut
}
}).scale({ x: this.scale, y: this.scale }).onTouch((event) => {
if (event.type === TouchType.Down) {
this.scale = 1.2;
} else if (event.type === TouchType.Up) {
this.scale = 1;
}
});
7.4 脉冲动画
@State opacity: number = 1;
RcIcon({
name: IconName.BELL,
iconSize: 30,
iconAnimation: {
duration: 1000,
curve: Curve.EaseInOut,
iterations: -1,
playMode: PlayMode.Alternate
}
}).opacity(this.opacity).onAppear(() => {
this.opacity = 0.3;
});
7.5 自定义动画曲线
import { curves } from '@kit.ArkUI';
RcIcon({
name: IconName.STAR,
iconSize: 30,
iconAnimation: {
duration: 500,
curve: curves.springMotion(0.6, 1.0)
}
});
7.6 动画使用建议
性能考虑:
- 避免同时运行过多动画
- 长时间动画使用
requestAnimationFrame
- 不可见时暂停动画
用户体验:
- 动画时长通常 200-500ms
- 避免过度动画影响阅读
- 提供动画开关选项
八、onIconClick 事件详解
8.1 事件定义
TouchEvent 对象包含:
type:触摸类型(Down/Move/Up/Cancel)
x, y:触摸坐标
timestamp:事件时间戳
target:触摸目标元素
8.2 基础点击
RcIcon({
name: IconName.HEART,
onIconClick: () => {
console.log('符号被点击');
}
});
8.3 状态切换
@State isFavorite: boolean = false;
RcIcon({
name: this.isFavorite ? IconName.HEART : IconName.HEART_OUTLINE,
color: this.isFavorite ? '#ff0000' : '#999999',
onIconClick: () => {
this.isFavorite = !this.isFavorite;
}
});
8.4 携带参数
handleIconClick(id: string) {
console.log(`符号 ${id} 被点击`);
}
RcIcon({
name: IconName.TRASH,
onIconClick: () => {
this.handleIconClick('item-123');
}
});
8.5 阻止事件冒泡
RcIcon({
name: IconName.CLOSE,
onIconClick: (event: TouchEvent) => {
event.stopPropagation();
this.closeDialog();
}
});
8.6 触摸反馈
@State isPressed: boolean = false;
private handleTouch = (event: TouchEvent): void => {
if (event.type === TouchType.Down) {
this.isPressed = true;
} else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
this.isPressed = false;
if (event.type === TouchType.Up) {
}
}
};
RcIcon({
name: IconName.BUTTON,
color: this.isPressed ? '#0066cc' : '#0080ff'
});
九、样式组合技巧
9.1 基础组合
RcIcon({ name: IconName.HOME, color: '#1890ff', iconSize: 24, iconRadius: 4 });
9.2 状态驱动样式
@State status: 'normal' | 'active' | 'disabled' = 'normal';
RcIcon({
name: IconName.STAR,
color: this.getStatusColor(),
iconSize: this.getStatusSize(),
onIconClick: this.status !== 'disabled' ? () => { this.toggleStatus() } : undefined
});
getStatusColor(): ResourceColor {
switch (this.status) {
case 'active': return '#ffaa00';
case 'disabled': return '#cccccc';
default: return '#666666';
}
}
9.3 主题适配
@StorageLink('isDarkMode') isDarkMode: boolean = false;
RcIcon({
name: IconName.MOON,
color: this.isDarkMode ? '#ffffff' : '#000000',
iconSize: 24
});
9.4 响应式设计
@State breakpoint: string = 'sm';
RcIcon({
name: IconName.LOGO,
iconSize: this.getResponsiveSize(),
iconRadius: this.getResponsiveRadius()
});
getResponsiveSize(): number {
const sizeMap = { xs: 16, sm: 20, md: 24, lg: 28 };
return sizeMap[this.breakpoint] || 20;
}
十、总结
10.1 属性设计原则
- 最小化必需参数:仅
name 为必需
- 合理默认值:提供开箱即用的体验
- 类型安全:严格的 TypeScript 类型约束
- 灵活性:支持多种使用方式和自定义
10.2 样式定制能力
- 颜色:支持任意颜色格式
- 尺寸:支持数字和字符串,响应式友好
- 圆角:统一和独立设置两种方式
- 动画:完整的动画参数支持
- 交互:标准的事件处理机制
10.3 最佳实践
- 优先使用 IconName 常量
- 保持样式一致性
- 注意性能优化
- 提供良好的交互反馈