[鸿蒙2025领航者闯关]图标资源统一管理
✅ AppIcons统一管理资源 ✅ 单色图标用SVG+fillColor ✅ 封装AppIcon组件复用 ✅ 遵循命名规范 ✅ 使用vp单位响应式。规范的图标管理提升开发效率!// ❌ 不推荐:分散使…
·
解决方案
- 系统图标使用
@Component
struct SystemIcons {
build() {
Row({ space: 16 }) {
// ✅ 使用系统图标
Image( r ( ′ s y s . m e d i a . o h o s i c p u b l i c a d d ′ ) ) . w i d t h ( 24 ) . h e i g h t ( 24 ) . f i l l C o l o r ( C o l o r . B l a c k ) ; I m a g e ( r('sys.media.ohos_ic_public_add')) .width(24) .height(24) .fillColor(Color.Black); Image( r(′sys.media.ohosicpublicadd′)) .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);
}
}
} - 自定义图标管理
/**
- 图标资源管理类
*/
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);
}
}
}
- 可复用图标组件
/**
- 图标组件
*/
@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
})
}
}
}
- 带标签的图标按钮
/**
- 图标按钮组件
*/
@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(‘点击编辑’);
}
})
}
}
}
- 动态图标状态
/**
- 可切换状态的图标
/
@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);
}
}
}
- 图标大小规范
/**
- 图标尺寸常量
*/
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’ });
}
})
最佳实践
- 图标命名规范
// ✅ 推荐命名
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 - 统一管理
// ✅ 推荐:集中管理
export class AppIcons {
static readonly ADD = KaTeX parse error: Expected 'EOF', got '}' at position 24: …edia.ic_add'); }̲ // ❌ 不推荐:分散使…r(‘app.media.ic_add’)); // 到处硬编码 - 响应式尺寸
// ✅ 推荐:使用vp单位
.width(24) // vp,自动适配屏幕密度
// ❌ 不推荐:使用px
.width(‘24px’) // 不同屏幕显示大小不一致
总结
图标管理要点:
✅ AppIcons统一管理资源 ✅ 单色图标用SVG+fillColor ✅ 封装AppIcon组件复用 ✅ 遵循命名规范 ✅ 使用vp单位响应式
规范的图标管理提升开发效率!
更多推荐



所有评论(0)