欢迎光临
我们一直在努力

【开源鸿蒙跨平台开发先锋训练营】Flutter框架下鸿蒙应用图标动态化实践指南

应用市场大部分热门榜单应用都是在设计视觉上下功夫,这次计划优化下页面中的图标,使用动态图标来提升下美感。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

文章目录

    • 一、目标与方案
    • 二、依赖变更
      • 2.1 pubspec.yaml
      • 2.2 说明
    • 三、新增文件:统一图标入口
    • 四、替换前后代码对比
      • 4.1 底部导航栏(root_page.dart)
      • 4.2 作品详情页(work_detail_page.dart)
      • 4.3 首页列表/网格切换(home_page.dart)
      • 4.4 我的页(profile_page.dart)
      • 4.5 收藏页(favorites_page.dart)
      • 4.6 发现页(search_page.dart)
      • 4.7 消息页(messages_page.dart)
      • 4.8 网络图片加载失败(network_image_widget.dart)
    • 五、效果
    • 六、使用提醒
    • 七、参考链接
    • 结束语

一、目标与方案

前段时间看到这个 lucide-animated.com,感觉不错,这些把他接入到项目中

  • 将项目中的图标全部替换为 Lucide 风格的动态图标,提升视觉与交互体验(参考 )。
  • 使用 Flutter 包 not_static_icons(基于 Lucide、无需 Rive/Lottie),在 lib/widgets/app_icons.dart 中封装统一入口,各页面通过该入口使用动态图标;包内未提供的少数图标仍使用 Material Icons 兜底。

二、依赖变更

2.1 pubspec.yaml

替换前:

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
dio: ^5.4.0
cached_network_image: ^3.3.1
shared_preferences: ^2.2.2

替换后:

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
dio: ^5.4.0
cached_network_image: ^3.3.1
shared_preferences: ^2.2.2
# 动态图标(Lucide 风格动画图标),提升视觉交互
not_static_icons: ^0.31.0

2.2 说明

  • 原计划使用 flutter_lucide_animated(与 lucide-animated.com 同源),因该包要求 Dart SDK >= 3.10.1,与当前项目 SDK ^3.6.2 不兼容,故改用 not_static_icons。
  • not_static_icons 同样基于 Lucide、提供 350+ 动画图标,支持 hover/触摸触发动画、可配置时长与颜色,且仅依赖 Flutter,与当前环境兼容。

三、新增文件:统一图标入口

文件:lib/widgets/app_icons.dart

  • 对外提供一组方法:appArrowBackIcon、appHeartIcon、appBookmarkIcon、appHomeIcon、appSearchIcon、appMessageIcon、appUserIcon、appChevronRightIcon、appSettingsIcon、appHistoryIcon、appLogOutIcon、appRefreshIcon、appUserPlusIcon、appSendIcon、appImageOffIcon、appCircleAlertIcon、appGridIcon、appListIcon 等。
  • 每个方法支持 size、color、interactive、部分支持 controller;默认动画时长 400ms。
  • 设置、添加用户 等包内无合适图标时使用 Material Icons(如 Icons.settings_outlined、Icons.person_add_alt_1),其余尽量使用 not_static_icons 中对应 Lucide 图标(如 BookSearchIcon、BotMessageSquareIcon、ArrowUpRightIcon、CameraOffIcon 等)。

四、替换前后代码对比

4.1 底部导航栏(root_page.dart)

项目替换前替换后
首页 icon: const Icon(Icons.home_outlined) / activeIcon: const Icon(Icons.home) icon: appHomeIcon(size: 26, color: unselectedColor, interactive: true) / activeIcon: appHomeIcon(size: 26, color: selectedColor, interactive: true)
发现 Icon(Icons.search_outlined) / Icon(Icons.search) appSearchIcon(size: 26, …)
消息 Icon(Icons.message_outlined) / Icon(Icons.message) appMessageIcon(size: 26, …)
我的 Icon(Icons.person_outline) / Icon(Icons.person) appUserIcon(size: 26, …)

效果:底部 Tab 切换时仍为选中/未选中颜色区分,图标在点击或悬停时可播放包自带的绘制/脉冲等动画,交互反馈更明显。


4.2 作品详情页(work_detail_page.dart)

位置替换前替换后
返回按钮 Icon(Icons.arrow_back_ios_new, color: Colors.white) appArrowBackIcon(size: 24, color: Colors.white, interactive: true)
收藏心形(顶部按钮) Icon(_isFavorite ? Icons.favorite : Icons.favorite_border, color: …) appHeartIcon(size: 26, color: _isFavorite ? Colors.red : Colors.white, interactive: true)
双击心形动画 Icon(Icons.favorite, size: 80, color: Colors.white) appHeartIcon(size: 80, color: Colors.white, interactive: false)
作者占位头像 Icon(Icons.person, color: Colors.white70) appUserIcon(size: 36, color: Colors.white70, interactive: false)
底部点赞/收藏数 Icon(Icons.favorite_border) / Icon(Icons.bookmark_border) appHeartIcon(size: 22, …) / appBookmarkIcon(size: 22, …)

效果:返回、收藏等按钮在点击时有动画反馈;底部统计仍为静态展示,风格与 Lucide 统一。


4.3 首页列表/网格切换(home_page.dart)

替换前替换后
Icon(_isGridView ? Icons.view_stream : Icons.grid_view, color: Colors.white, size: 24) _isGridView ? appListIcon(size: 24, color: Colors.white, interactive: true) : appGridIcon(size: 24, color: Colors.white, interactive: true)

效果:切换列表/网格时,图标本身带动画(如 Grid2x2Icon / LayersIcon),更易感知当前模式。


在这里插入图片描述

4.4 我的页(profile_page.dart)

位置替换前替换后
返回 / 设置按钮 Icon(Icons.arrow_back_ios_new) / Icon(Icons.settings_outlined) appArrowBackIcon(size: 24, interactive: true) / appSettingsIcon(size: 24)
设置项右侧箭头 trailing: const Icon(Icons.chevron_right) trailing: appChevronRightIcon(size: 22, interactive: true)
获赞/收藏统计 _StatChip(icon: Icons.favorite_border, …) 等 _StatChip(iconWidget: appHeartIcon(…, color: primary, interactive: false), …)
菜单项 _MenuItem(icon: Icons.favorite, …) 等,leading: Icon(icon, …),trailing: Icon(Icons.chevron_right) _MenuItem(iconWidget: appHeartIcon(…), …),trailing: appChevronRightIcon(…)
历史记录空态 Icon(Icons.history, size: 64, color: Colors.grey[400]) appHistoryIcon(size: 64, color: Colors.grey[400], interactive: false)
图片占位/失败 Icon(Icons.image_not_supported) appImageOffIcon(size: 24, interactive: false)

效果:列表项与设置项在点击时箭头/心形等有动画;统计与空态为静态图标,风格统一。


4.5 收藏页(favorites_page.dart)

位置替换前替换后
空态 Icon(Icons.favorite_border, size: 64, color: Colors.grey[400]) appHeartIcon(size: 64, color: Colors.grey[400], interactive: false)
返回 / 列表项箭头、占位图 同上模式 appArrowBackIcon / appChevronRightIcon / appImageOffIcon

4.6 发现页(search_page.dart)

位置替换前替换后
搜索框前缀 prefixIcon: Icon(Icons.search, color: Colors.grey[600], size: 22) prefixIcon: appSearchIcon(size: 22, color: Colors.grey[600], interactive: false)
刷新 Icon(Icons.refresh) appRefreshIcon(size: 24, interactive: true)
无结果空态 Icon(Icons.search_off, size: 64, …) appSearchIcon(size: 64, color: Colors.grey[400], interactive: false)
卡片封面占位 / 头像占位 / 收藏心形 Icon(Icons.image_not_supported) / Icon(Icons.person, …) / Icon(isFavorite ? Icons.favorite : Icons.favorite_border, …) appImageOffIcon / appUserIcon / appHeartIcon

4.7 消息页(messages_page.dart)

位置替换前替换后
添加会话 Icon(Icons.person_add_alt_1) appUserPlusIcon(size: 24)(Material 兜底)
空态 Icon(Icons.chat_bubble_outline, size: 64, …) appMessageIcon(size: 64, color: Colors.grey[400], interactive: false)
发送按钮 icon: const Icon(Icons.send) icon: appSendIcon(size: 24, color: Colors.white, interactive: true)
返回 Icon(Icons.arrow_back_ios_new) appArrowBackIcon(size: 24, interactive: true)

4.8 网络图片加载失败(network_image_widget.dart)

替换前替换后
const Icon(Icons.error_outline, color: Colors.white, size: 50) appCircleAlertIcon(size: 50, color: Colors.white, interactive: false)

效果:加载失败时显示带轻微动画的警示图标,风格与全局一致。


五、效果

维度替换前替换后
视觉 全部为 Material 静态图标 主要为 Lucide 风格线型图标,部分带绘制/脉冲/旋转等动画
交互 仅点击跳转或状态变化,图标本身无动效 底部 Tab、返回、收藏、刷新、发送、列表项等处的图标在点击或悬停时可播放动画,反馈更明确
一致性 Material 与系统风格一致 全应用统一为 Lucide 系风格,仅少数(如设置、添加用户)保留 Material
性能 字体图标,体量小 not_static_icons 为 SVG 动画,按需使用;未增加 Rive/Lottie 等重依赖

鸿蒙app动态图标使用效果

六、使用提醒

  • 放在可点击容器内时一律用 interactive: false:当图标作为 BottomNavigationBarItem、IconButton、ListTile 的 leading/trailing、或 GestureDetector 子节点时,必须设 interactive: false,否则图标内部的手势会拦截点击,导致 Tab 切换失效、按钮/列表项无反应。修复后 Tab 与各类按钮点击均正常。
  • 纯展示(空态、占位、统计小图标):interactive: false,不响应触摸,仅展示静态或初始帧。
  • 尺寸与颜色:通过 app_icons.dart 各方法的 size、color 统一控制,与页面主题色配合(如 Theme.of(context).colorScheme.primary)。
  • 新增图标:优先在 app_icons.dart 中增加封装,若 not_static_icons 无合适图标再用 Icon(Icons.xxx) 并注明原因。

  • 七、参考链接

    • Lucide Animated(Web 展示)
    • not_static_icons(pub.dev)

    结束语

    感谢阅读本帖,如对贴中内容有意见和建议的,欢迎与我联系交流,也欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

    赞(0)
    未经允许不得转载:171主机测评 » 【开源鸿蒙跨平台开发先锋训练营】Flutter框架下鸿蒙应用图标动态化实践指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址