HarmonyOS 鸿蒙Next中图标资源怎样统一管理
HarmonyOS 鸿蒙Next中图标资源怎样统一管理 应用开发需要管理大量图标:
- 系统图标vs自定义图标
- 图标统一管理
- 动态切换图标颜色
- SVG vs PNG选择
解决方案
1. 系统图标使用
@Component
struct SystemIcons {
build() {
Row({ space: 16 }) {
// ✅ 使用系统图标
Image($r('sys.media.ohos_ic_public_add'))
.width(24)
.height(24)
.fillColor(Color.Black);
Image($r('sys.media.ohos_ic_public_delete'))
.width(24)
.height(24)
.fillColor(Color.Red);
Image($r('sys.media.ohos_ic_public_search'))
.width(24)
.height(24);
}
}
}
2. 自定义图标管理
/**
* 图标资源管理类
*/
export class AppIcons {
// ✅ 统一管理图标资源
static readonly ADD = $r('app.media.ic_add');
static readonly DELETE = $r('app.media.ic_delete');
static readonly EDIT = $r('app.media.ic_edit');
static readonly SEARCH = $r('app.media.ic_search');
static readonly FILTER = $r('app.media.ic_filter');
static readonly SETTINGS = $r('app.media.ic_settings');
// 功能模块图标
static readonly ITEM = $r('app.media.ic_item');
static readonly HEALTH = $r('app.media.ic_health');
static readonly BABY = $r('app.media.ic_baby');
static readonly ASSET = $r('app.media.ic_asset');
static readonly FINANCE = $r('app.media.ic_finance');
// 状态图标
static readonly SUCCESS = $r('app.media.ic_success');
static readonly WARNING = $r('app.media.ic_warning');
static readonly ERROR = $r('app.media.ic_error');
static readonly INFO = $r('app.media.ic_info');
}
// ✅ 使用
@Component
struct IconUsage {
build() {
Row() {
Image(AppIcons.ADD)
.width(24)
.height(24);
Image(AppIcons.DELETE)
.width(24)
.height(24)
.fillColor(Color.Red);
}
}
}
3. 可复用图标组件
/**
* 图标组件
*/
@Component
export struct AppIcon {
@Prop icon: Resource;
@Prop size: number = 24;
@Prop color?: ResourceColor;
build() {
Image(this.icon)
.width(this.size)
.height(this.size)
.fillColor(this.color)
.objectFit(ImageFit.Contain);
}
}
// ✅ 使用
@Component
struct IconDemo {
build() {
Row({ space: 16 }) {
AppIcon({
icon: AppIcons.ADD,
size: 24,
color: AppColors.PRIMARY
})
AppIcon({
icon: AppIcons.DELETE,
size: 32,
color: Color.Red
})
}
}
}
4. 带标签的图标按钮
/**
* 图标按钮组件
*/
@Component
export struct IconButton {
@Prop icon: Resource;
@Prop label: string;
@Prop onClick?: () => void;
@Prop iconSize: number = 24;
@Prop iconColor?: ResourceColor;
build() {
Column({ space: 4 }) {
Image(this.icon)
.width(this.iconSize)
.height(this.iconSize)
.fillColor(this.iconColor);
Text(this.label)
.fontSize(12)
.fontColor('#666666');
}
.padding(8)
.borderRadius(8)
.onClick(() => {
if (this.onClick) {
this.onClick();
}
})
}
}
// ✅ 使用
@Component
struct ActionBar {
build() {
Row({ space: 24 }) {
IconButton({
icon: AppIcons.ADD,
label: '添加',
iconColor: AppColors.PRIMARY,
onClick: () => {
console.info('点击添加');
}
})
IconButton({
icon: AppIcons.EDIT,
label: '编辑',
onClick: () => {
console.info('点击编辑');
}
})
}
}
}
5. 动态图标状态
/**
* 可切换状态的图标
*/
@Component
struct ToggleIcon {
@State isActive: boolean = false;
build() {
Image(this.isActive ? AppIcons.HEART_FILLED : AppIcons.HEART_OUTLINE)
.width(24)
.height(24)
.fillColor(this.isActive ? Color.Red : '#999999')
.onClick(() => {
animateTo({ duration: 200 }, () => {
this.isActive = !this.isActive;
});
})
}
}
/**
* 加载状态图标
*/
@Component
struct LoadingIcon {
@State isLoading: boolean = true;
build() {
if (this.isLoading) {
LoadingProgress()
.width(24)
.height(24)
.color(AppColors.PRIMARY);
} else {
Image(AppIcons.SUCCESS)
.width(24)
.height(24)
.fillColor(Color.Green);
}
}
}
6. 图标大小规范
/**
* 图标尺寸常量
*/
export class IconSizes {
static readonly SMALL = 16; // 小图标
static readonly NORMAL = 24; // 常规图标
static readonly LARGE = 32; // 大图标
static readonly XLARGE = 48; // 超大图标
}
// ✅ 使用
Image(AppIcons.ADD)
.width(IconSizes.NORMAL)
.height(IconSizes.NORMAL);
图标格式选择
SVG vs PNG
| 特性 | SVG | PNG |
|---|---|---|
| 缩放 | ✅ 无损 | ❌ 失真 |
| 颜色控制 | ✅ fillColor | ❌ 不可改 |
| 文件大小 | 小 | 大 |
| 适用场景 | 单色图标 | 复杂图片 |
推荐方案
// ✅ 推荐:单色图标用SVG
resources/base/media/
ic_add.svg // 添加图标
ic_delete.svg // 删除图标
ic_edit.svg // 编辑图标
// ✅ 推荐:复杂图片用PNG
resources/base/media/
bg_splash.png // 启动页背景
img_avatar.png // 用户头像
img_banner.png // Banner图片
实战案例
案例1: 底部导航栏
@Component
struct TabBar {
@State currentIndex: number = 0;
private tabs: TabInfo[] = [
{ id: 0, icon: AppIcons.HOME, label: '首页' },
{ id: 1, icon: AppIcons.CATEGORY, label: '分类' },
{ id: 2, icon: AppIcons.PROFILE, label: '我的' }
];
@Builder
buildTab(tab: TabInfo, index: number) {
Column({ space: 4 }) {
Image(tab.icon)
.width(24)
.height(24)
.fillColor(this.currentIndex === index ? AppColors.PRIMARY : '#999999');
Text(tab.label)
.fontSize(12)
.fontColor(this.currentIndex === index ? AppColors.PRIMARY : '#999999');
}
}
build() {
Row() {
ForEach(this.tabs, (tab: TabInfo, index: number) => {
this.buildTab(tab, index)
.layoutWeight(1)
.onClick(() => {
this.currentIndex = index;
})
})
}
.width('100%')
.height(56)
.backgroundColor(Color.White);
}
}
案例2: 空状态页面
@Component
struct EmptyState {
@Prop icon: Resource = AppIcons.EMPTY;
@Prop message: string = '暂无数据';
@Prop actionText?: string;
@Prop onAction?: () => void;
build() {
Column({ space: 16 }) {
Image(this.icon)
.width(120)
.height(120)
.fillColor('#CCCCCC');
Text(this.message)
.fontSize(14)
.fontColor('#999999');
if (this.actionText && this.onAction) {
Button(this.actionText)
.onClick(() => {
if (this.onAction) {
this.onAction();
}
});
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center);
}
}
// 使用
EmptyState({
icon: AppIcons.NO_DATA,
message: '还没有添加物品',
actionText: '立即添加',
onAction: () => {
router.pushUrl({ url: 'pages/AddItemPage' });
}
})
最佳实践
1. 图标命名规范
// ✅ 推荐命名
ic_add.svg // ic_功能.svg
ic_delete.svg
ic_home_filled.svg // ic_功能_状态.svg
ic_heart_outline.svg
// ❌ 不推荐
add.svg
delete_icon.svg
home.png
2. 统一管理
// ✅ 推荐:集中管理
export class AppIcons {
static readonly ADD = $r('app.media.ic_add');
}
// ❌ 不推荐:分散使用
Image($r('app.media.ic_add')); // 到处硬编码
3. 响应式尺寸
// ✅ 推荐:使用vp单位
.width(24) // vp,自动适配屏幕密度
// ❌ 不推荐:使用px
.width('24px') // 不同屏幕显示大小不一致
总结
图标管理要点:
✅ AppIcons统一管理资源 ✅ 单色图标用SVG+fillColor ✅ 封装AppIcon组件复用 ✅ 遵循命名规范 ✅ 使用vp单位响应式
规范的图标管理提升开发效率!
更多关于HarmonyOS 鸿蒙Next中图标资源怎样统一管理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next中图标资源统一管理通过资源索引实现。在resources/base/media目录下放置图标文件,系统自动生成资源ID。开发者可在代码中通过$r('app.media.icon_name')引用,或在XML中通过@media:icon_name调用。支持多设备适配,可在resources下按屏幕密度(如ldpi、hdpi)或设备类型(如tablet)建立子目录存放差异化资源。资源类型限定为PNG、JPG、SVG等格式,SVG需经转换工具处理。
在HarmonyOS Next中,图标资源的统一管理主要通过资源管理系统和声明式UI范式实现。
1. 系统图标与自定义图标
- 系统图标:使用
Resource对象引用预置的$r('sys.media.ic_xxx')资源。这些图标由系统提供并维护,风格统一。 - 自定义图标:将图标文件(如SVG、PNG)放置在工程的
resources/base/media/目录下。通过$r('app.media.icon_name')方式引用。建议按模块或功能建立子目录进行分类管理。
2. 统一管理与引用
在resources/base/element/string.json中可定义图标资源的ID映射,实现逻辑名与资源文件的解耦。在UI组件中,使用资源引用语法:
Image($r('app.media.home_icon'))
.width(24)
.height(24)
3. 动态切换颜色
对于SVG图标,可通过fillColor属性动态修改颜色:
Image($r('app.media.ic_setting'))
.fillColor(Color.Blue) // 动态设置颜色
对于多色图标或需要更复杂控制的情况,建议使用SVG格式并通过组件属性控制。
4. SVG与PNG选择
- SVG:矢量格式,无损缩放,支持通过属性动态修改颜色、大小。适合界面图标、可交互元素。
- PNG:位图格式,适合复杂细节图像(如照片、游戏纹理)。需提供不同密度的版本(如
base/medium/high/xhigh目录)。
最佳实践:
- 建立统一的图标资源目录结构
- 界面图标优先使用SVG格式
- 在
string.json中维护图标ID,提高可维护性 - 复杂场景可封装自定义图标组件,统一处理尺寸、颜色等属性
这种管理方式能有效提升图标资源的维护效率和应用性能。

