
文章目录前言图标方案对比SymbolGlyph 系统图标自定义 SVG 资源Svg 组件绘制图标库管理方案动态着色写在最后前言之前做项目图标都是切 PNG1x 2x 3x 一堆文件塞得资源目录乱七八糟。后来发现 HarmonyOS7 的 SymbolGlyph 直接用系统图标爽到飞起——直到产品说这个图标系统里没有要自定义的。好吧自定义 SVG 图标这条路迟早得走。今天把从系统图标到自定义 SVG 的完整方案梳理一遍。图标是 UI 里看着不起眼但特别重要的东西。一个 App 动辄几十上百个图标管理不好就是灾难。HarmonyOS7 给了三条路系统 Symbol 图标—— 零配置拿来就用Svg 组件绘制—— 纯代码画适合简单图形SVG 资源文件—— 设计师出图开发引用最常用三条路各有利弊往下看。图标方案对比方案适用场景优点缺点SymbolGlyph系统标准图标零配置、支持动效、自动适配字体粗细只有系统预置图标约433个Svg 组件绘制简单几何图形纯代码、动态可控复杂图形代码量爆炸SVG 资源文件自定义设计图标任意图形、矢量不失真需要管理资源文件PNG 图片位图/特殊效果兼容性好多分辨率、文件大、不能动态着色我的建议系统图标能用的就用不够的用 SVG 资源别再用 PNG 了。SymbolGlyph 系统图标SymbolGlyph 是 HarmonyOS7 最省心的图标方案直接引用系统图标库EntryComponentstruct SymbolGlyphDemo{build(){Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap,alignItems:ItemAlign.Center}){SymbolGlyph($r(sys.symbol.ohos_wifi)).fontSize(28).fontColor([Color.Black]).renderingStrategy(SymbolRenderingStrategy.SINGLE)SymbolGlyph($r(sys.symbol.ohos_folder_badge_plus)).fontSize(28).fontColor([Color.Blue]).renderingStrategy(SymbolRenderingStrategy.SINGLE)SymbolGlyph($r(sys.symbol.airplane_fill)).fontSize(28).fontColor([Color.Red]).renderingStrategy(SymbolRenderingStrategy.SINGLE)SymbolGlyph($r(sys.symbol.checkmark_circle)).fontSize(28).fontColor([Color.Black,Color.Green,Color.White]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR)}.width(100%).padding(16).justifyContent(FlexAlign.SpaceAround)}}关键代码讲解$r(sys.symbol.ohos_wifi)—— 引用系统图标sys.symbol.是固定前缀后面接图标标识名.fontSize(28)—— 图标大小跟字号一致设 28 就是 28x28vp.fontColor([Color.Black])—— 颜色数组单色渲染时只生效第一个renderingStrategy—— 渲染策略决定了多颜色怎么分配到图层渲染策略详解策略说明SINGLE单色只用第一个颜色MULTIPLE_OPACITY分层一个颜色按不同透明度渲染各层MULTIPLE_COLOR多色每个图层独立设色图标名称去哪找华为开发者官网有完整的 Symbol 图标库每个图标下面都标着标识名。自定义 SVG 资源系统图标不够用的时候把设计师给的 SVG 文件放进资源目录resources/ base/ media/ icon_home.svg icon_search.svg icon_profile.svg代码中引用Image($r(app.media.icon_home)).width(24).height(24).fillColor(#333333).objectFit(ImageFit.Contain)关键代码讲解$r(app.media.icon_home)—— 引用 media 目录下的 SVG 文件.fillColor(#333333)——SVG 专用属性动态修改填充颜色PNG 不支持这个.objectFit(ImageFit.Contain)—— 保持比例缩放这里的.fillColor()就是 SVG 比 PNG 强的地方——同一张 SVG 可以在不同场景复用不同颜色。Svg 组件绘制如果图标很简单比如一个圆形、一个箭头可以直接用 Svg 组件代码画EntryComponentstruct SvgDrawDemo{build(){Column({space:24}){Shape(){Circle().width(48).height(48).fill(#007DFF)}.width(48).height(48)Shape(){Path().commands(M12 4 L24 24 L0 24 Z).fill(#ff4444)}.width(24).height(24).viewBox({x:0,y:0,width:24,height:24})Shape(){Line().startPoint([0,0]).endPoint([24,24]).stroke(Color.Black).strokeWidth(2)Line().startPoint([24,0]).endPoint([0,24]).stroke(Color.Black).strokeWidth(2)}.width(24).height(24)}.padding(24)}}关键代码讲解Shape—— 所有绘制组件的容器类似 SVG 的svg标签Circle()—— 画圆width/height控制直径fill填充颜色Path().commands()—— 自定义路径M移动L画线Z闭合。M12 4 L24 24 L0 24 Z画了一个三角形viewBox()—— 定义坐标系类似 SVG 的 viewBox 属性确保路径在不同尺寸下比例正确Line()—— 画直线startPoint/endPoint是起止坐标复杂图形别硬画代码维护成本太高。交给设计师出 SVG 文件才是正道。图标库管理方案图标一多就得有管理方案不然东一个西一个改起来要命。推荐结构resources/ base/ media/ icons/ tab/ icon_home.svg icon_search.svg icon_message.svg icon_profile.svg action/ icon_add.svg icon_delete.svg icon_edit.svg status/ icon_success.svg icon_warning.svg icon_error.svg命名规范前缀按用途分类tab_、action_、status_全小写下划线别用驼峰一个图标一个文件别把所有图标塞一个 SVG 里动态着色图标着色是高频需求——Tab 栏选中变色、暗黑模式变色、主题切换变色。SVG 的.fillColor()就是干这个的Componentstruct TabIconItem{Propicon:ResourcePropisActive:booleanfalsebuild(){Image(this.icon).width(24).height(24).fillColor(this.isActive?#007DFF:#999999).objectFit(ImageFit.Contain)}}EntryComponentstruct DynamicColorDemo{StatecurrentTab:number0privatetabs[{icon:$r(app.media.icon_home),label:首页},{icon:$r(app.media.icon_search),label:搜索},{icon:$r(app.media.icon_profile),label:我的}]build(){Row(){ForEach(this.tabs,(tab:Recordstring,Resource|string,index:number){Column(){TabIconItem({icon:tab.iconasResource,isActive:this.currentTabindex})Text(tab.labelasstring).fontSize(12).fontColor(this.currentTabindex?#007DFF:#999999).margin({top:4})}.layoutWeight(1).onClick((){this.currentTabindex})})}.width(100%).height(56).padding({top:8,bottom:8})}}关键代码讲解.fillColor(this.isActive ? #007DFF : #999999)——核心选中蓝色未选中灰色一个属性搞定Prop—— 子组件接收父组件传值单向绑定够用同一张 SVG 文件不同颜色渲染——这就是矢量的魅力写在最后图标方案就三句话能用 SymbolGlyph 就用省心省力还带动效自定义图标用 SVG 资源文件fillColor 动态着色是杀手锏别用 PNG都 2026 了还切多分辨率图片太古老了图标管理也是工程问题命名规范、目录结构提前定好后面维护才不痛苦。