news 2026/6/22 23:49:21

[鸿蒙2025领航者闯关]图标资源统一管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[鸿蒙2025领航者闯关]图标资源统一管理

解决方案

  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单位响应式

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/22 3:29:17

区分__proto__和prototype

彻底区分__proto__与prototype:从JS底层到Vue实战 要彻底理解 __proto__ 和 prototype,需穿透 JavaScript 原型链的底层逻辑,再结合 Vue 框架的实例体系落地应用。本文从「归属、作用、关联、误区、实战」五个核心维度拆解,补充大…

作者头像 李华
网站建设 2026/6/23 17:05:32

西门子PLC地址知识点

西门子 PLC 的地址体系是按数据类型和存储区域划分的,核心分为过程映像区、位存储区、数据块区、定时器 / 计数器区等,不同区域的地址格式和用途差异显著,直接决定了 C# 与 PLC 通信时的地址配置和数据解析逻辑。一、 核心存储区域与地址格式…

作者头像 李华
网站建设 2026/6/22 21:31:59

EmotiVoice开源项目依赖项管理最佳实践

EmotiVoice 开源项目依赖项管理与工程化实践 在智能语音助手、虚拟偶像和AIGC内容创作日益普及的今天,用户对语音合成系统的要求早已超越“能说话”的基础功能。人们期待的是富有情感、自然流畅、具备个性化音色的声音体验。然而,传统文本转语音&#x…

作者头像 李华
网站建设 2026/6/22 20:55:42

如何彻底解决腾讯游戏卡顿问题:sguard_limit资源限制器完整指南

如何彻底解决腾讯游戏卡顿问题:sguard_limit资源限制器完整指南 【免费下载链接】sguard_limit 限制ACE-Guard Client EXE占用系统资源,支持各种腾讯游戏 项目地址: https://gitcode.com/gh_mirrors/sg/sguard_limit 还在为玩腾讯游戏时的频繁卡顿…

作者头像 李华
网站建设 2026/6/23 17:40:58

MiniGPT-4终极优化指南:5个简单技巧实现3倍推理加速

MiniGPT-4终极优化指南:5个简单技巧实现3倍推理加速 【免费下载链接】MiniGPT-4 Open-sourced codes for MiniGPT-4 and MiniGPT-v2 (https://minigpt-4.github.io, https://minigpt-v2.github.io/) 项目地址: https://gitcode.com/gh_mirrors/mi/MiniGPT-4 …

作者头像 李华
网站建设 2026/6/23 12:19:45

鼠标性能测试终极指南:从新手到专家的完整解决方案

鼠标性能测试终极指南:从新手到专家的完整解决方案 【免费下载链接】MouseTester 项目地址: https://gitcode.com/gh_mirrors/mo/MouseTester 你是否曾经在游戏中因为鼠标响应延迟而错失关键操作?或是在设计工作中感觉光标移动不够精准&#xff…

作者头像 李华