HarmonyOS ArkTS 多页面应用的设计一致性与架构思维
引子:五个工具,一套视觉语言
小工具百宝箱有五个工具——二维码、单位换算、随机决策、颜色提取、倒计时。功能各不相同,但打开任何一个页面,深色渐变背景、白色标题、圆角卡片、统一的返回按钮,视觉上一看就是"同一个应用"。
这种一致性不是巧合,而是刻意设计的结果。今天就从五个页面的共性出发,聊聊多页面应用的设计系统和架构思维。
完整效果
共性分析:五个页面都有的元素
打开任意两个页面对比,会发现它们有大量相同的结构:
| 元素 | 二维码 | 单位换算 | 随机决策 | 颜色提取 | 倒计时 |
|---|---|---|---|---|---|
| 渐变背景 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 返回按钮 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 页面标题 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 工具主色 | #4F6EF7 | #34C759 | #FF6B35 | #AF52DE | #FF2D55 |
| 圆角卡片 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 深色背景色 | #2A2A3E | #2A2A3E | #2A2A3E | #2A2A3E | #1E1E32 |
五个页面用了同一套设计语言,只是主色调不同。
渐变背景:统一的视觉基底
.linearGradient({
direction: GradientDirection.Bottom,
colors: [['#1A1A2E', 0.0], ['#16213E', 0.5], ['#0F3460', 1.0]]
})

五个页面的背景完全一样——从深蓝到更深蓝的三段渐变。这个渐变有三个作用:
- 统一感:所有页面共享同一个背景,切换时不会"跳"
- 深度感:渐变比纯色有层次,看起来更高级
- 衬托内容:深色背景让白色文字和彩色元素更醒目
为什么不每个页面用不同的渐变
用不同渐变会让每个页面更有"个性",但代价是失去统一性。用户从一个页面跳到另一个,视觉上会"断裂"。对于工具箱这种"多个工具共存"的应用,统一性比个性更重要。
导航栏:三种模式
五个页面的导航栏结构相似,但有细微差异:
模式一:纯返回 + 标题
Row() {
Text('←').fontSize(22).fontColor('#FF6B35').onClick(() => router.back())
Text('🎲 随机决策').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF').margin({left:12})
}.width('100%').padding({left:20,right:20,top:50,bottom:12})

随机决策、颜色提取、倒计时用这种模式——只有返回按钮和标题。
模式二:返回 + 标题 + 操作按钮
Row() {
Text('←').fontSize(22).fontColor('#FF2D55').onClick(() => router.back())
Text('⏳ 倒计时').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF').margin({left:12})
Blank()
Button('+ 新增').fontSize(13).height(34).borderRadius(10)
.backgroundColor('#FF2D55').fontColor('#FFFFFF')
.onClick(() => { this.showAdd = !this.showAdd; })
}.width('100%').padding({left:20,right:20,top:50,bottom:12})

倒计时页面在标题右边加了"+ 新增"按钮。Blank() 把按钮推到最右边。
模式三:返回 + 标题(居左对齐)
二维码和单位换算的标题在左边,和返回按钮同行。
为什么返回按钮的 color 不同
每个页面的返回按钮颜色和该工具的主色一致——二维码用蓝色(#4F6EF7),单位换算用绿色(#34C759),随机决策用橙色(#FF6B35)。这是"品牌色"在细节上的体现。
颜色系统:每个工具自己的主色
const TOOLS: ToolItem[] = [
{ name: '二维码生成', color: '#4F6EF7' }, // 蓝色
{ name: '单位换算', color: '#34C759' }, // 绿色
{ name: '随机决策', color: '#FF6B35' }, // 橙色
{ name: '颜色提取', color: '#AF52DE' }, // 紫色
{ name: '倒计时', color: '#FF2D55' }, // 红色
];
五种颜色的选择
五种颜色饱和度相近(都在 60-80% 之间),在深色背景上都能看清。但色相不同(蓝、绿、橙、紫、红),用户可以通过颜色快速识别工具。
颜色在页面中的应用
每个工具的颜色出现在三个地方:
- 首页卡片:
backgroundColor(item.color) - 导航栏返回按钮:
.fontColor('#4F6EF7') - 页面内的强调元素:按钮、滑块、进度条等
为什么不统一用一种颜色
统一用一种颜色会让页面更简洁,但用户在首页靠颜色区分工具。如果所有页面都是蓝色,用户打开后需要看标题才知道"这是哪个工具"。颜色是最直观的识别方式。
字号系统:四个层级
五个页面的字号高度一致:
| 层级 | 字号 | 粗细 | 用途 |
|---|---|---|---|
| 标题 | 18px | Bold | 页面标题、卡片名称 |
| 正文 | 14-16px | Medium | 输入框文字、列表项 |
| 辅助 | 11-12px | Normal | 描述文字、标签 |
| 强调 | 24-40px | Bold/Lighter | 结果数字、大标题 |
为什么强调数字用 Lighter 而不是 Bold
Text(this.result).fontSize(40).fontWeight(FontWeight.Lighter)
Lighter 是更细的字重。大号数字用细体比粗体更优雅——粗体大数字会显得笨重,细体更精致。
间距系统:20px 基准
五个页面的左右边距都是 20px:
.padding({left:20, right:20, top:50, bottom:...})
为什么用 20px
20px 是移动端常见的边距值——太小(8px)会显得拥挤,太大(40px)会浪费空间。20px 在大多数屏幕上都能保持良好的可读性。
top: 50 的原因
导航栏的 top padding 是 50px,留出状态栏的空间。如果不用 50px,标题会和状态栏重叠。
卡片样式:圆角和阴影
.borderRadius(16)
.shadow({radius: 8, color: '#00000022', offsetY: 4})
.backgroundColor('#1E1E32')
圆角 16px
五个页面的卡片圆角都是 16px(或 18px)。大圆角让卡片更柔和,符合现代 UI 趋势。
阴影的统一
阴影的参数略有不同(radius 8-12,color 22%-44% 透明度),但整体风格一致——深色阴影,向下偏移。
背景色的微调
大部分页面用 #2A2A3E,倒计时用 #1E1E32。略有差异,但都在深色范围内,视觉上不会冲突。
路由架构:push + back
import { router } from '@kit.ArkUI';
// 首页跳转
navTo(page: string): void {
router.pushUrl({ url: page });
}
// 子页面返回
Text('←').onClick(() => router.back())
为什么用 push 而不是 replace
pushUrl 把目标页面压入栈顶,用户按返回键能回到首页。如果用 replaceUrl,首页会被替换掉,用户按返回键直接退出应用。
页面栈的管理
五个工具页面都用 pushUrl 进入,用 back 返回。页面栈结构:
首页 → 工具页面 → (用户按返回)→ 首页
简单清晰,不需要额外管理。
不一致性:可以改进的地方
五个页面虽然整体一致,但有一些细微差异:
1. 背景色不完全统一
- 二维码、单位换算、随机决策:卡片
#2A2A3E - 颜色提取:无卡片
- 倒计时:卡片
#1E1E32
2. 阴影参数不完全统一
- 二维码:
shadow({radius:12, color: this.hex+'66'}) - 单位换算:无阴影
- 随机决策:
shadow({radius:8, color:'#FF6B3522'})
3. 标题的 emoji 不统一
- 二维码:
📱 - 单位换算:
📐 - 随机决策:
🎲 - 颜色提取:
🎨 - 倒计时:
⏳
emoji 本身没问题,但如果要更统一,可以不用 emoji,纯文字标题。
4. 返回按钮的大小
五个页面的返回按钮都是 fontSize(22),但颜色不同。如果要更统一,可以固定一个颜色(比如白色)。
设计系统的提取
如果要让五个页面更一致,可以提取一个设计系统:
// theme/CommonTheme.ts
export const THEME = {
// 渐变背景
gradient: {
direction: GradientDirection.Bottom,
colors: [['#1A1A2E', 0.0], ['#16213E', 0.5], ['#0F3460', 1.0]]
},
// 字号
fontSize: {
title: 18,
body: 15,
caption: 12,
result: 40
},
// 间距
spacing: {
page: 20,
navTop: 50,
navBottom: 12
},
// 卡片
card: {
radius: 16,
bgColor: '#1E1E32',
shadow: { radius: 8, color: '#00000022', offsetY: 4 }
}
};

然后每个页面引用 THEME 而不是硬编码值:
.linearGradient(THEME.gradient)
.padding({left: THEME.spacing.page, right: THEME.spacing.page})
好处
修改一个地方,所有页面同步更新。比如要把渐变背景改成从上到下,只需要改 THEME.gradient,不需要改五个文件。
坏处
增加了间接层,代码可读性降低。对于只有五个页面的小应用,直接硬编码可能更简单。
踩坑记录
坑 1:渐变背景的层级
渐变背景加在最外层 Column 上。如果加在内层 Column 上,滚动时背景不会跟着动。
坑 2:导航栏的 top padding
不同设备的状态栏高度不同。固定 50px 在大部分设备上没问题,但在某些设备上可能不够。可以用 env(statusbar_height) 动态获取。
坑 3:router.back() 的行为
router.back() 返回上一页。如果页面栈为空(比如直接进入工具页面),back() 会退出应用。需要确保从首页进入工具页面。
坑 4:ForEach 的 key
五个页面的 ForEach 都没有显式指定 key。对于静态列表没问题,但如果列表会动态增删,需要指定 key 避免渲染错误。
坑 5:颜色的可访问性
白色文字(#FFFFFF)在深色背景上对比度足够,但灰色文字(#666666)可能在某些屏幕上不够清晰。可以用 WebAIM 对比度检查工具验证。
代码改进建议
1. 提取公共组件
把导航栏、卡片、按钮等公共组件提取成独立文件,五个页面引用。
2. 统一阴影参数
把阴影参数统一成一个常量,避免每个页面自己写。
3. 统一背景色
把卡片背景色统一成一个值,减少视觉差异。
4. 加载动画
页面切换时可以加过渡动画,让跳转更流畅。
5. 深色模式适配
当前固定深色主题。如果要支持浅色模式,需要把颜色值提取成变量。
总结
小工具百宝箱的五个页面共享一套设计语言——深色渐变背景、20px 边距、18px 粗体标题、16px 圆角卡片、每个工具自己的主色。这种一致性让用户在切换工具时不会"迷失"。
适用边界:这个部分适合用作多页面应用设计一致性的学习案例,涵盖了设计系统提取、颜色系统、字号层级、间距系统、路由架构等核心知识点。但如果要上架应用商店,还需要补充公共组件提取、统一阴影/背景色、加载动画、深色模式适配等内容。
更多推荐


所有评论(0)