🌈 Flutter + OpenHarmony 设计系统实战:构建统一、美观、无障碍的跨端 UI 体系
作者 :晚霞的不甘
日期 :2025年12月5日
标签:Flutter · OpenHarmony · Design System · UI/UX · 响应式设计 · 无障碍 · 鸿蒙生态

引言:当代码遇见美学------UI 不只是"好看"
在 OpenHarmony 的超级终端时代,用户可能在手机、手表、车机、智慧屏 上使用你的应用。
若每个设备都采用不同设计语言:
- 用户体验割裂
- 开发维护成本倍增
- 品牌识别度下降
更严重的是,不符合《OpenHarmony 人因设计规范》的应用将无法通过 AppGallery 审核。
本文将指导你从零构建一套跨设备、高一致性、强可维护、无障碍友好的 Flutter + OpenHarmony 设计系统,涵盖色彩、排版、组件、动效、适配五大核心模块,助你实现:
- 设计开发效率提升 40%+
- UI 一致性达 95% 以上
- 无障碍评分 ≥ 90 分(华为 Accessibility Checker)
一、设计系统全景架构
plaintext
┌──────────────────────────────────────┐
│ Design Tokens │ ← 色彩 / 间距 / 字体 / 圆角
├──────────────────────────────────────┤
│ Foundation │ ← 布局 / 网格 / 响应式规则
├──────────────────────────────────────┤
│ Components │ ← 按钮 / 卡片 / 导航 / 表单
├──────────────────────────────────────┤
│ Patterns │ ← 页面模板 / 交互流程
└──────────────────────────────────────┘
✅ 核心原则:
- 原子化:组件由 Design Tokens 构建
- 响应式:一套代码适配五端
- 语义化 :颜色/间距有业务含义(如
--color-primary)- 无障碍优先:对比度 ≥ 4.5:1,支持 TalkBack
二、Design Tokens:视觉语言的原子单元
2.1 色彩系统(Color Palette)
| 类型 | Light 模式 | Dark 模式 | 用途 |
|---|---|---|---|
| Primary | #007AFF |
#0A84FF |
主按钮、选中状态 |
| Surface | #FFFFFF |
#1C1C1E |
背景、卡片底色 |
| Text Primary | #1D1D1F |
#FFFFFF |
标题文字 |
| Error | #FF3B30 |
#FF453A |
错误提示 |
🎨 实现方式(Flutter):
dart
// lib/theme/colors.dart
class OhColors {
static const primary = Color(0xFF007AFF);
static const surface = Color(0xFFFFFFFF);
static const textPrimary = Color(0xFF1D1D1F);
}
2.2 间距与圆角(Spacing & Radius)
| Token | 值 (dp) | 用途 |
|---|---|---|
--space-xs |
4 | 图标内边距 |
--space-s |
8 | 元素间隔 |
--space-m |
16 | 卡片内边距 |
--radius-s |
8 | 按钮圆角 |
--radius-l |
24 | 大卡片圆角 |
dart
// lib/theme/spacing.dart
class OhSpacing {
static const xs = 4.0;
static const s = 8.0;
static const m = 16.0;
}
2.3 字体系统(Typography)
| 层级 | 字号 (sp) | 字重 | 用途 |
|---|---|---|---|
| Display Large | 34 | Bold | 首页标题 |
| Headline Medium | 24 | SemiBold | 页面标题 |
| Body Large | 17 | Regular | 正文 |
| Label Small | 11 | Medium | 按钮标签 |
💡 注意:手表端字体 ≥ 18sp,车机 ≥ 20sp。
三、响应式布局:一套 UI 适配五端
3.1 设备分类策略
| 设备类型 | 屏幕尺寸 | 布局策略 |
|---|---|---|
| Wearable | < 2" | 单列、极简、大触控区 |
| Phone | 4--7" | 单列、手势导航 |
| Tablet | 8--12" | 双栏、富交互 |
| Car | 10--15" | 大按钮、语音主导、防误触 |
| TV | > 32" | 焦点导航、遥控器优化 |
3.2 Flutter 实现:设备感知布局
dart
Widget build(BuildContext context) {
final device = OhDeviceType.of(context); // 自定义设备类型检测
return Scaffold(
body: device.isTv || device.isCar
? TvOptimizedLayout() // 焦点 + 大字体
: device.isWearable
? WatchCompactLayout() // 单列滚动
: ResponsivePhoneLayout(), // 默认手机布局
);
}
3.3 网格系统(Grid System)
- 手机:4 列网格(每列 8dp gutter)
- 平板:8 列网格
- 智慧屏:12 列网格,元素居中
dart
// 使用 flutter_staggered_grid_view
StaggeredGrid.count(
crossAxisCount: device.isTv ? 12 : device.isTablet ? 8 : 4,
mainAxisSpacing: OhSpacing.s,
crossAxisSpacing: OhSpacing.s,
children: [...],
)
四、原子组件库:高复用、高一致性
4.1 按钮(Button)
| 变体 | 样式 | 适用场景 |
|---|---|---|
| Primary | 实心主色 | 主要操作(如"提交") |
| Secondary | 白底描边 | 次要操作(如"取消") |
| Text | 无背景 | 内联操作(如"查看更多") |
dart
// lib/components/oh_button.dart
class OhButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
final OhButtonVariant variant;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
Color bgColor = variant == OhButtonVariant.primary
? OhColors.primary
: Colors.transparent;
return Container(
height: 48,
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(OhRadius.s),
border: variant == OhButtonVariant.secondary
? Border.all(color: OhColors.outline)
: null,
),
child: Text(text, style: theme.textTheme.labelLarge),
);
}
}
4.2 卡片(Card)
- 统一阴影:
elevation: 2 - 内边距:
padding: EdgeInsets.all(OhSpacing.m) - 圆角:
borderRadius: OhRadius.l
4.3 导航栏(Navigation Bar)
| 设备 | 导航形式 |
|---|---|
| 手机 | 底部 TabBar |
| 车机 | 左侧垂直菜单 |
| 智慧屏 | 顶部横幅 + 遥控器焦点 |
五、动效设计:流畅而不打扰
5.1 动效原则
- 时长:进入动画 ≤ 300ms,退出 ≤ 200ms
- 缓动 :使用
Curves.easeOut(自然减速) - 克制:非必要不加动效
5.2 Flutter 实现
dart
// 页面切换淡入
PageRouteBuilder(
pageBuilder: (_, __, ___) => NextPage(),
transitionsBuilder: (_, anim, __, child) {
return FadeTransition(opacity: anim, child: child);
},
)
// 按钮点击反馈
InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(OhRadius.s),
child: OhButton(...),
)
六、无障碍(Accessibility):让每个人都能用
6.1 关键要求
| 项目 | 标准 |
|---|---|
| 颜色对比度 | ≥ 4.5:1(正文) / ≥ 3:1(大字) |
| 触控区域 | ≥ 48×48 dp |
| 语义标签 | 所有图标按钮需 Semantics(label: "搜索") |
| 焦点顺序 | 逻辑清晰(车机/TV 必须支持) |
6.2 Flutter 无障碍实践
dart
// 为图标按钮添加语义
Semantics(
label: '打开设置',
child: IconButton(icon: Icon(Icons.settings), onPressed: _openSettings),
)
// 动态调整字体(响应系统设置)
Text(
'Hello',
style: TextStyle(fontSize: MediaQuery.textScaleFactorOf(context) * 17),
)
6.3 测试工具
- 华为 DevEco Accessibility Scanner:自动检测对比度、标签缺失
- TalkBack / VoiceOver:手动验证读屏体验
七、设计开发协作流程
7.1 工具链集成
Tokens Extractor Figma 设计稿 Design Tokens JSON Flutter Code Generator OhTheme.dart 组件库 业务页面
7.2 版本管理
- Design Tokens 语义化版本(如
@oh-design/tokens@1.2.0) - 组件库独立发布,业务项目按需升级
八、验收标准与 Checklist
✅ 所有颜色来自 OhColors
✅ 所有间距使用 OhSpacing
✅ 手机/平板/车机均有 UI 预览
✅ 无障碍扫描评分 ≥ 90
✅ 深色模式完整适配
✅ 字体缩放至 200% 仍可用
结语:设计系统,是产品长期主义的体现
一套好的设计系统,让:
- 设计师专注体验创新,而非重复造轮子
- 开发者高效交付,无需纠结像素对齐
- 用户在任何设备上都感到熟悉与安心
🎨 行动建议:
- 今天就定义
OhColors和OhSpacing- 明天封装
OhButton组件- 下周完成首页基于新系统的重构
因为一致的体验,是最好的品牌语言。
附录:资源推荐
- OpenHarmony 人因设计指南
- Flutter Design System 模板(GitHub)
- 华为 DevEco Design Kit(Figma 插件)
美,不是装饰,而是功能与情感的和谐统一。