页面预览

前言

在移动应用开发中,图标系统是品牌视觉和用户体验的重要组成部分。HarmonyOS 提供了 SymbolGlyph 组件,支持使用系统内置的 Symbol 图标,同时提供丰富的着色和样式定制能力。

“海风日记“在整个项目中统一使用 SymbolGlyph 系统图标,设计了清晰的颜色令牌体系,确保每个图标的颜色、大小和风格保持一致。本文将从源码出发,深入讲解 SymbolGlyph 的使用方法、着色机制、颜色令牌体系以及最佳实践。


一、SymbolGlyph 组件概述

1.1 什么是 SymbolGlyph

SymbolGlyph 是 HarmonyOS 提供的系统图标组件,通过 $r('sys.symbol.xxx') 引用系统内置的 Symbol 图标资源。与传统的图片图标相比,SymbolGlyph 有以下优势:

特性 SymbolGlyph 图片图标(PNG) 字体图标(IconFont)
体积 无额外资源 需要打包图片 需要加载字体文件
缩放 矢量无损 位图有锯齿 矢量无损
颜色 支持动态着色 固定颜色 单色
多色 支持多色 Symbol 不支持 不支持
系统适配 自动适配主题 需手动适配 需手动适配

1.2 系统 Symbol 图标的引用方式

HarmonyOS 提供了丰富的系统 Symbol 图标,通过 $r('sys.symbol.xxx') 引用:

// 常用的系统 Symbol 图标
$r('sys.symbol.house')              // 首页
$r('sys.symbol.calendar')           // 日历
$r('sys.symbol.clock')              // 时钟/回顾
$r('sys.symbol.person')             // 个人
$r('sys.symbol.plus')               // 加号
$r('sys.symbol.magnifyingglass')    // 搜索
$r('sys.symbol.chevron_left')       // 左箭头
$r('sys.symbol.chevron_right')      // 右箭头
$r('sys.symbol.xmark')              // 关闭
$r('sys.symbol.square_and_pencil')  // 编辑

1.3 海风日记中使用的 Symbol 图标统计

“海风日记“全项目共使用了 30+ 个不同的 Symbol 图标,以下是按功能分类的统计:

分类 图标 使用场景
导航 house, calendar, clock, person 底部 Tab 栏
操作 plus, xmark, chevron_left, chevron_right 导航栏操作
编辑 square_and_pencil, camera, face_smiling, trash 写日记工具栏
搜索 magnifyingglass, list_bullet, flame 搜索页面
设置 gearshape, moon, lock_shield, phone 设置菜单
数据 externaldrive, arrow_up, arrow_down, arrow_clockwise 数据管理
其他 pin, ellipsis_circle, shareplay, checkmark_circle_fill 多处功能

二、SymbolGlyph 的着色机制

2.1 基础颜色配置

SymbolGlyph 使用 fontColor 属性设置颜色,语法为数组形式

SymbolGlyph($r('sys.symbol.house'))
  .fontSize(22)
  .fontColor([COLOR_TAB_ACTIVE])  // 数组语法

2.2 选中态与未选中态的颜色切换

“海风日记“的 Tab 导航栏根据选中状态切换图标颜色:

SymbolGlyph(icon)
  .fontSize(22)
  .fontColor([
    this.currentIndex === index
      ? COLOR_TAB_ACTIVE   // '#F5A623' 橙色
      : COLOR_TAB_INACTIVE  // '#C0BAB4' 暖灰
  ])

2.3 多色 Symbol 的着色

对于支持多色的 Symbol 图标,fontColor 数组的每个元素对应一个颜色层级:

// 多色 Symbol 示例(假设图标支持 3 层颜色)
SymbolGlyph($r('sys.symbol.person_crop_circle_fill'))
  .fontSize(22)
  .fontColor([
    COLOR_AMBER,    // 第一层颜色
    COLOR_PRIMARY,  // 第二层颜色
    COLOR_WHITE     // 第三层颜色
  ])

2.4 颜色数组的层级对应关系

fontColor 数组索引与 Symbol 颜色层级的对应关系:

数组索引 层级 说明 示例颜色
[0] 第一层 主要填充色 #C8956A(琥珀)
[1] 第二层 次要区域色 #F5A623(橙色)
[2] 第三层 细节线条色 #FFFFFF(白色)

提示:对于单色 Symbol,传入一个元素的数组即可;对于多色 Symbol,需要按顺序传入对应数量的颜色值。


三、项目中 SymbolGlyph 的典型用法

3.1 Tab 导航栏图标

Index.ets 中的 Tab 图标,使用条件渲染控制选中态颜色:

@Builder
tabBuilder(index: number, label: string, icon: Resource) {
  Column({ space: 2 }) {
    SymbolGlyph(icon)
      .fontSize(22)
      .fontColor([
        this.currentIndex === index
          ? COLOR_TAB_ACTIVE    // '#F5A623'
          : COLOR_TAB_INACTIVE  // '#C0BAB4'
      ])

    Text(label)
      .fontSize(10)
      .fontColor(this.currentIndex === index
        ? COLOR_TAB_ACTIVE
        : COLOR_TAB_INACTIVE)
  }
}

3.2 浮动按钮图标

中间的“写日记“浮动按钮使用白色加号图标:

Button() {
  SymbolGlyph($r('sys.symbol.plus'))
    .fontSize(26)
    .fontColor(['#FFFFFF'])
}
.width(56).height(56)
.borderRadius(28)
.backgroundColor('#F5A623')

3.3 导航栏操作按钮

在日记详情页中,编辑和更多操作按钮:

Row({ space: 8 }) {
  // 编辑按钮
  Button() {
    SymbolGlyph($r('sys.symbol.square_and_pencil'))
      .fontSize(18).fontColor([COLOR_TEXT_MAIN])
  }
  .backgroundColor('transparent').width(36).height(36)

  // 更多按钮
  Button() {
    SymbolGlyph($r('sys.symbol.ellipsis_circle'))
      .fontSize(18).fontColor([COLOR_TEXT_MAIN])
  }
  .backgroundColor('transparent').width(36).height(36)
}

3.4 搜索页图标

搜索框中的放大镜图标:

Row() {
  SymbolGlyph($r('sys.symbol.magnifyingglass'))
    .fontSize(16)
    .fontColor([COLOR_TEXT_HINT])

  TextInput({ placeholder: '搜索日记内容、标签...' })
    .layoutWeight(1).height(36)
}
.height(40)
.backgroundColor('#FFFFFF')
.borderRadius(INPUT_RADIUS)
.padding({ left: 12, right: 8 })

3.5 设置菜单图标

设置菜单中的每一行图标:

Row({ space: 12 }) {
  SymbolGlyph(item.icon)
    .fontSize(18)
    .fontColor([item.danger ? '#D06060' : COLOR_AMBER])

  Text(item.label)
    .fontSize(15)
    .fontColor(item.danger ? '#D06060' : COLOR_TEXT_MAIN)
    .layoutWeight(1)

  SymbolGlyph($r('sys.symbol.chevron_right'))
    .fontSize(14)
    .fontColor([COLOR_TEXT_HINT])
}
.width('100%').height(50)
.padding({ left: PAGE_PADDING, right: PAGE_PADDING })

四、颜色令牌体系

4.1 SymbolGlyph 的颜色管理

“海风日记“通过 Colors.ets 集中管理所有颜色,SymbolGlyph 使用的颜色分为以下几类:

颜色常量 色值 用途
COLOR_TAB_ACTIVE #F5A623 Tab 选中态图标
COLOR_TAB_INACTIVE #C0BAB4 Tab 未选中态图标
COLOR_AMBER #C8956A 设置菜单、工具栏图标
COLOR_TEXT_MAIN #2D2926 导航栏操作图标
COLOR_TEXT_HINT #BEB8B2 辅助图标、箭头
COLOR_DANGER #D06060 删除、危险操作图标
COLOR_WHITE #FFFFFF 暗色背景上的图标

4.2 颜色常量的定义

// Colors.ets — 颜色令牌体系
/** 底部导航 Tab 未选中色 */
export const COLOR_TAB_INACTIVE = '#C0BAB4'
/** 底部导航 Tab 选中色 */
export const COLOR_TAB_ACTIVE = '#F5A623'
/** 琥珀棕 — 品牌文案、标签、辅助色 */
export const COLOR_AMBER = '#C8956A'
/** 主文字 — 暖棕黑 */
export const COLOR_TEXT_MAIN = '#2D2926'
/** 提示/占位文字 */
export const COLOR_TEXT_HINT = '#BEB8B2'
/** 错误/危险色 */
export const COLOR_DANGER = '#D06060'

4.3 颜色使用规范

在项目中使用 SymbolGlyph 颜色时,遵循以下规范:

  1. 导航类图标:使用 COLOR_TAB_ACTIVE / COLOR_TAB_INACTIVE
  2. 操作类图标:使用 COLOR_AMBER(琥珀棕)
  3. 导航栏图标:使用 COLOR_TEXT_MAIN(暖棕黑)
  4. 辅助图标:使用 COLOR_TEXT_HINT(暖灰)
  5. 危险操作:使用 COLOR_DANGER(红色)
  6. 高亮强调:使用 COLOR_PRIMARY(橙色)

五、SymbolGlyph 的高级用法

5.1 图标大小与权重

fontSize 控制图标大小,fontWeight 控制图标线条粗细:

SymbolGlyph($r('sys.symbol.house'))
  .fontSize(22)              // 图标尺寸
  .fontWeight(FontWeight.Bold)  // 线条粗细

5.2 图标渲染模式

renderingStrategy 控制图标的渲染策略:

SymbolGlyph($r('sys.symbol.person_crop_circle_fill'))
  .renderingStrategy(SymbolRenderingStrategy.SINGLE)  // 单色模式
  // 或
  .renderingStrategy(SymbolRenderingStrategy.MULTI_COLOR)  // 多色模式
  // 或
  .renderingStrategy(SymbolRenderingStrategy.HIERARCHICAL)  // 层级模式
渲染模式 说明 适用场景
SINGLE 单色渲染,所有层级使用同一种颜色 简单图标
MULTI_COLOR 多色渲染,使用 fontColor 数组中的不同颜色 复杂图标
HIERARCHICAL 层级渲染,通过透明度区分层级 需要层次感的图标

5.3 图标效果

effectStrategy 控制图标的视觉效果:

SymbolGlyph($r('sys.symbol.plus'))
  .effectStrategy(SymbolEffectStrategy.SCALE)  // 缩放效果
  // 或
  .effectStrategy(SymbolEffectStrategy.BOUNCE)  // 弹跳效果
  // 或
  .effectStrategy(SymbolEffectStrategy.PULSE)  // 脉冲效果

5.4 图标动画

SymbolGlyph 支持内置的动画效果:

SymbolGlyph($r('sys.symbol.plus'))
  .fontSize(26)
  .fontColor(['#FFFFFF'])
  .effectStrategy(SymbolEffectStrategy.SCALE)  // 点击时缩放动画

六、SymbolGlyph 与 Resource 管理

6.1 $r() 资源引用函数

$r() 是 HarmonyOS 中的资源引用函数,用于引用系统或应用资源:

// 引用系统 Symbol 图标
$r('sys.symbol.house')

// 引用应用图片资源
$r('$media:app_icon')

// 引用应用字符串资源
$r('$string:app_name')

// 引用应用颜色资源
$r('$color:start_window_background')

6.2 资源类型与引用格式

资源类型 引用格式 示例
系统 Symbol 图标 $r('sys.symbol.xxx') $r('sys.symbol.house')
应用图片 $r('$media:xxx') $r('$media:app_icon')
应用字符串 $r('$string:xxx') $r('$string:app_name')
应用颜色 $r('$color:xxx') $r('$color:primary')

6.3 在数据模型中使用 Resource 类型

在“海风日记“中,菜单项数据使用 Resource 类型存储图标引用:

interface MenuItemData {
  icon: Resource          // 图标资源引用类型
  label: string
  url: string
  danger?: boolean
}

// 初始化数据
const menuItems: MenuItemData[] = [
  { icon: $r('sys.symbol.person_crop_circle_fill'), label: '个人信息', url: '...' },
  { icon: $r('sys.symbol.gearshape'), label: '个性设置', url: '...' },
  { icon: $r('sys.symbol.moon'), label: '深色模式', url: '...' },
]

七、常见问题与最佳实践

7.1 图标不显示

问题:SymbolGlyph 显示为空白或占位符。

原因:引用的 Symbol 名称不存在或拼写错误。

解决方案:检查 Symbol 名称是否正确,参考[系统 Symbol 图标列表](https://atomgit.com/openharmony/docs。

// 正确的引用方式
$r('sys.symbol.plus')        // 正确
$r('sys.symbol.add')         // 错误:add 不存在
$r('sys.symbol.plus.circle') // 可能是 plus_circle 或 plus.circle

7.2 颜色不生效

问题:设置了 fontColor 但图标颜色没有变化。

原因:使用了不支持多色着色的图标,或 fontColor 数组长度不够。

解决方案

// 单色图标,只传入一个颜色
SymbolGlyph($r('sys.symbol.house'))
  .fontColor([COLOR_TAB_ACTIVE])

// 多色图标,传入对应层级的颜色
SymbolGlyph($r('sys.symbol.person_crop_circle_fill'))
  .fontColor([COLOR_AMBER, COLOR_PRIMARY])

7.3 图标大小不一致

问题:不同 Symbol 图标显示大小不一致。

原因:不同 Symbol 的设计尺寸有差异。

解决方案:统一设置 fontSize

// 统一设置图标大小
SymbolGlyph(icon).fontSize(22)  // Tab 栏图标统一 22vp
SymbolGlyph(icon).fontSize(18)  // 操作按钮图标统一 18vp
SymbolGlyph(icon).fontSize(14)  // 辅助箭头统一 14vp

7.4 性能优化

  1. 避免动态创建 Resource 引用$r() 应在初始化时创建,而非在循环中重复调用
  2. 复用颜色常量:使用预定义的颜色常量,避免重复写色值
  3. 合理使用渲染模式:简单图标使用单色模式,减少渲染开销

总结

本文详细讲解了 HarmonyOS 中 SymbolGlyph 系统图标在“海风日记“中的统一使用方案:

  1. SymbolGlyph 基础:系统图标的引用方式、优势和特点
  2. 着色机制fontColor 数组语法、选中态切换、多色着色
  3. 典型用法:Tab 导航、浮动按钮、操作按钮、搜索图标、设置菜单
  4. 颜色令牌体系:SymbolGlyph 颜色分类管理规范
  5. 高级用法:渲染模式、效果策略、图标动画
  6. Resource 管理$r() 资源引用、数据模型中的 Resource 类型

通过统一使用 SymbolGlyph 系统图标,我们实现了零额外图标资源统一着色风格自动适配系统主题的效果,大大减少了应用包体积和维护成本。

下一篇文章将深入讲解 Router 路由管理,包括 pushUrl、replaceUrl、back 以及参数传递的完整用法,敬请期待。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

Logo

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

更多推荐