解决方案

  1. 系统图标使用
    @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);
      }
    }
    }
  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);
      }
    }
    }
  1. 可复用图标组件
    /**
  • 图标组件
    */
    @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
        })
      }
    }
    }
  1. 带标签的图标按钮
    /**
  • 图标按钮组件
    */
    @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(‘点击编辑’);
          }
        })
      }
    }
    }
  1. 动态图标状态
    /**
  • 可切换状态的图标
    /
    @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);
      }
    }
    }
  1. 图标大小规范
    /**
  • 图标尺寸常量
    */
    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 = KaTeX parse error: Expected 'EOF', got '}' at position 24: …edia.ic_add'); }̲ ​ // ❌ 不推荐:分散使…r(‘app.media.ic_add’));  // 到处硬编码
  3. 响应式尺寸
    // ✅ 推荐:使用vp单位
    .width(24)  // vp,自动适配屏幕密度

    // ❌ 不推荐:使用px
    .width(‘24px’)  // 不同屏幕显示大小不一致
    总结
    图标管理要点:

✅ AppIcons统一管理资源 ✅ 单色图标用SVG+fillColor ✅ 封装AppIcon组件复用 ✅ 遵循命名规范 ✅ 使用vp单位响应式

规范的图标管理提升开发效率!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐