2025/12/18 3:03:08
网站建设
项目流程
解决方案
系统图标使用 @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 . m e d ia . 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 llC o l or ( C o l or . Bl a c k ) ; I ma g e ( 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单位响应式
规范的图标管理提升开发效率!