很多页面看起来“不丑”,但就是没重点。按钮、卡片、图片、文字全部老老实实铺在一个平面上,用户第一眼看到的不是重点,而是一堆同时抢注意力的信息。HarmonyOS 7 把“空间化”进一步带到应用设计里之后,我更愿意把它理解成一次界面组织方式的变化:不是单纯把卡片做得更立体,而是重新安排内容的前后关系,让重要的信息自然往前走,不重要的信息适当往后退。
在这里插入图片描述

1. 为什么传统平面 UI 开始不够用了

先说一个很常见的页面。

假设我们做的是一个“设备控制中心”:顶部是欢迎信息,中间是一张设备状态卡片,下面有灯光、空调、门锁、场景模式等快捷入口,最底下还有最近操作记录。

功能其实一点都不少,布局也没什么明显问题。用 ColumnRowGrid 把这些内容排整齐,再配上圆角、背景色和一点阴影,页面很快就能做出来。

问题是,整齐不等于层级清楚

当设备状态卡片、快捷入口、历史记录都处在近似的视觉平面上时,用户打开页面以后,需要自己判断:

  • 哪一块是当前最重要的信息?
  • 哪一块可以操作?
  • 哪一块只是辅助说明?
  • 我点开某张卡片以后,页面的注意力应该落在哪里?

这类问题在简单页面里不明显,一旦页面信息量上来,就很容易出现一种感觉:所有东西都在,但所有东西都差不多重要。

说白了,这就像把一屋子的东西全部摊在地板上。你确实一眼都能看到,可要找钥匙的时候,反而不一定快。

在这里插入图片描述

传统平面 UI 常见的问题大概可以归成三类。

1.1 信息主次靠颜色和字号硬撑

以前我们最常用的办法是:

  • 标题大一点;
  • 主卡片颜色深一点;
  • 重要按钮换成高饱和色;
  • 不重要的文字改成灰色。

这些方法当然有效,但它们基本都在同一个二维平面里解决问题。页面越复杂,需要叠加的视觉规则越多,最后反而可能变得很吵。

1.2 操作状态缺少“位置变化”

比如用户点开一张卡片,我们可能只是弹出一个 Dialog,或者直接跳转新页面。

从功能上没问题,但用户对“我刚刚操作的对象”和“新内容从哪里来的”这层关系,主要靠记忆去补。

如果界面能让主卡片向前强调、背景内容适当后退,用户会更容易理解当前状态。

1.3 动效很多,但动效之间没关系

还有一种更常见:为了让页面高级一点,到处加 scale、渐隐、弹跳、位移。

结果每个组件都挺忙,整个页面却没有统一逻辑。

所以真正的问题不是“动画不够多”,而是缺少一套空间层级规则


2. 空间化 UI,不等于给卡片加个阴影

HarmonyOS 7 官方对空间化方向的描述很直接:从平面到立体,让沉浸空间为用户所见所感。

但这里特别容易产生一个误区:看到“立体”,马上想到 3D 旋转、透视、复杂光效。

其实对绝大多数普通应用来说,没必要一上来就做真正的三维场景。

我更愿意把移动端里的空间化 UI 拆成四件事:

  1. 信息有前后关系;
  2. 不同层承担不同职责;
  3. 交互发生时,视觉焦点会迁移;
  4. 动效服务于层级变化,而不是为了炫。

也就是说,空间化 UI 首先是一个信息架构问题,其次才是视觉效果问题。

HarmonyOS 7 在设计侧进一步强调沉浸光感、材质、空间属性和交互响应;在开发侧,我们仍然可以使用 ArkUI 熟悉的布局、图形变换和动画能力,把这种“前后关系”做出来。

这反而是好事。

因为开发者不需要把整个页面推倒重来,也不需要为了“空间化”就引入一套完全不同的开发模式。很多现有页面,本质上都是可以渐进式改造的。


3. 先别写代码:把页面拆成五个层级

这次我以一个“智能设备控制中心”页面为例。

原来的页面结构大概是:

Column
├── Header
├── DeviceStatusCard
├── QuickActions
├── SceneCards
└── HistoryList

从代码树看没问题,但从视觉关系看,它们几乎都是并列的。

我会先把它重新理解成五个空间层:

L0 背景层
L1 基础内容层
L2 核心信息层
L3 当前交互层
L4 反馈层

L0:背景层

背景层负责建立整体氛围。

它不应该抢内容,不应该放太多高对比元素。可以是纯色、渐变、弱化后的大图,也可以结合 HarmonyOS 7 的材质和沉浸光感设计。

重点只有一句话:它是舞台,不是演员。

L1:基础内容层

这里放页面里“需要存在,但当前不是最重要”的信息,比如历史记录、次级状态、辅助入口。

当用户进入某个核心操作时,这一层应该允许被适当弱化,例如降低一点透明度、轻微缩小或者向后退。

L2:核心信息层

比如当前设备状态卡片、主要任务卡片、主视觉内容。

这是用户进入页面后最应该先看到的东西。

它和基础内容层不能只靠“字号大 4px”来区分,而应该在尺寸、位置、留白、阴影、材质和交互响应上形成完整差异。

L3:当前交互层

当用户点击设备卡片以后,操作面板、调节面板或者展开内容应该进入这一层。

此时页面不是简单“多出来一个弹窗”,而是发生了一次空间关系调整:

当前对象往前,非当前内容往后。

L4:反馈层

Toast、状态提示、短时反馈、操作结果都属于这一层。

它的特点是层级最高,但停留时间最短。

在这里插入图片描述

请添加图片描述

这个拆法有一个很大的好处:后面做动画的时候,不需要每次临时想“这个组件怎么动比较酷”。

先看它属于哪一层,再决定它应该前移、后退、放大、缩小还是淡出,逻辑会顺很多。


4. 用 ArkUI 把“层级关系”真正写出来

页面结构确定以后,代码实现反而不复杂。

这类需要前后叠放的页面,我通常会先用 Stack 搭出整体结构,再在内部使用 ColumnRow 等常规布局完成每一层自己的排版。

下面给一个简化版骨架:

@Entry
@Component
struct SpatialDashboard {
  @State detailOpened: boolean = false

  build() {
    Stack({ alignContent: Alignment.Center }) {
      // L0:背景层
      Column()
        .width('100%')
        .height('100%')
        .backgroundColor('#F4F6FA')

      // L1:基础内容层
      Column() {
        this.Header()
        this.HistoryArea()
      }
      .width('100%')
      .height('100%')
      .padding(20)
      .opacity(this.detailOpened ? 0.72 : 1)
      .scale({
        x: this.detailOpened ? 0.97 : 1,
        y: this.detailOpened ? 0.97 : 1
      })
      .translate({
        y: this.detailOpened ? 12 : 0
      })

      // L2:核心信息层
      this.DeviceCard()

      // L3:当前交互层
      if (this.detailOpened) {
        this.ControlPanel()
      }
    }
    .width('100%')
    .height('100%')
  }
}

这段代码里最重要的其实不是 Stack 本身,而是下面三个属性:

.opacity(...)
.scale(...)
.translate(...)

它们组合起来以后,就能非常直观地表达“退后”和“向前”。

比如进入详情状态时,基础内容层:

  • 透明度略降;
  • 尺寸缩小一点;
  • 位置向下移动一点。

视觉上用户会自然感觉:这个区域不是消失了,只是暂时退到了后面。

这和直接 visibility(false) 的体验完全不一样。

4.1 为什么优先用 scale / translate,而不是频繁改 width / position

这里有一个很实际的性能点。

ArkUI 官方的动画优化指南明确提到:如果通过 widthheightposition 等布局属性持续改变组件尺寸和位置,系统需要重新计算布局;而 scaletranslate 这类图形变换是在布局结果之上做显示变换,通常可以减少不必要的重新布局。

所以类似“卡片轻微前移”“背景退后”“内容缩放”这类空间化动画,能用图形变换解决时,我会优先考虑图形变换。

不是因为代码短,而是因为这类效果本来就属于“显示状态变化”,没必要每一帧都把整个布局重新算一遍。


5. 把主卡片真正“推到前面”

核心卡片可以再单独做一次状态变化。

例如:

@Builder
DeviceCard() {
  Column() {
    Text('客厅设备')
      .fontSize(20)
      .fontWeight(FontWeight.Bold)

    Text('4 个设备在线 · 空气质量良好')
      .fontSize(14)
      .opacity(0.65)

    Row() {
      Button('打开控制')
        .onClick(() => {
          this.getUIContext().animateTo({
            duration: 240,
            curve: Curve.EaseOut
          }, () => {
            this.detailOpened = true
          })
        })
    }
    .margin({ top: 20 })
  }
  .width('86%')
  .padding(24)
  .borderRadius(28)
  .backgroundColor('#FFFFFF')
  .scale({
    x: this.detailOpened ? 1.03 : 1,
    y: this.detailOpened ? 1.03 : 1
  })
  .translate({
    y: this.detailOpened ? -42 : 0
  })
  .shadow({
    radius: this.detailOpened ? 28 : 12,
    color: '#22000000',
    offsetX: 0,
    offsetY: this.detailOpened ? 12 : 5
  })
}

点击以后,卡片会轻微放大、上移,同时阴影范围增加。

注意我这里故意用了“轻微”。

空间化 UI 最怕的就是所有变化都用力过猛。

scale11.03,用户能感觉到它往前走了,但不会出现“卡片突然扑到脸上”的感觉。

translate 也不需要几十上百像素乱飞,只要能把视觉焦点从背景里拉出来就够了。

请添加图片描述


6. 真正的改造重点:不是效果变多,而是信息重新排队

如果把改造前后的页面放在一起看,会发现真正明显的变化其实不是“多了几个动画”。

改造前:

标题
卡片
按钮
卡片
列表
按钮
列表

用户自己找重点。

改造后:

背景
  ↓
基础信息
  ↓
核心卡片
  ↓
当前操作
  ↓
即时反馈

系统开始主动告诉用户什么更重要。

这就是我理解的空间层级价值。

请添加图片描述

而且这种思路很适合逐步改造旧项目。

你完全没必要第一天就把整个 App 做成“空间世界”。

先找最关键的 1~2 个页面:

  • 首页;
  • 详情页;
  • 播放页;
  • 控制中心;
  • 数据仪表盘;
  • 商品展示页。

把用户最关注的核心对象提出来,把背景信息退下去,先把前后关系做对,效果通常就已经很明显。


7. 交互不是越炫越好,空间感也要有“刹车”

做到这里,最容易开始上头。

主卡片能放大,那旁边卡片是不是也旋转一下?

页面能后退,那背景是不是再加一层模糊?

按钮能跟随焦点,那是不是再加点弹簧动画?

我的建议是:先忍住。

空间化 UI 的目的不是证明开发者会多少种动画,而是让页面更容易理解。

我一般会用三个标准判断一个动效该不该留。

7.1 它有没有告诉用户“发生了什么”

比如主卡片上移、背景退后,这个动画表达的是“当前操作对象被提到前面”。

有明确语义,可以留。

如果只是因为页面看起来有点空,所以让按钮左右晃一下,那就没什么必要。

7.2 它有没有建立连续关系

用户点的是 A,接下来出现的是 A 的控制面板,那么动画应该让用户感觉这两个东西是连续的。

如果 A 在左边消失,控制面板突然从右边飞进来,虽然热闹,但关系反而断了。

7.3 它会不会让用户等

动画再高级,只要让用户产生“你倒是快点”的感觉,就过头了。

普通点击反馈、卡片聚焦、面板展开,我会更倾向于短时长、快响应。空间感靠层级变化来建立,不靠拖时间建立。

请添加图片描述


8. 一个很容易忽略的坑:层级多了,点击区域也可能乱

空间化页面里经常会出现叠层。

看起来是下面一张卡片,实际上上面可能还压着一个透明组件。

结果就是:

用户看得到按钮,却点不到。

这类问题光看代码有时候不容易找。

DevEco Studio 的 ArkUI Inspector 在这里很实用。除了看组件树、属性、状态变量和边框,现在还支持按组件粒度做 3D 展开应用。

换句话说,可以把页面组件像“分层模型”一样展开,看谁压在谁上面。

这对空间化页面尤其合适。

因为我们本身就在强调层级,最终当然也应该从层级角度检查:

  • 是否有不必要的透明遮挡;
  • 交互层是不是压住了基础层;
  • 某些组件是不是层层嵌套得过深;
  • 页面关闭详情以后,临时交互层有没有真正下树;
  • 点击区域和视觉区域是否一致。

这比只盯着模拟器截图靠谱很多。


9. DevEco Studio 里我会怎么验证这个页面

做完页面以后,我一般不会只说一句“跑起来没报错”就算结束。

至少会从下面五个角度再看一次。

9.1 第一眼焦点是不是正确

启动页面以后,不操作。

问自己一个很简单的问题:

三秒以内,我最先看到的是不是核心卡片?

如果答案不是,那空间层级基本还没有建立起来。

9.2 聚焦以后,背景有没有退得太狠

背景退得太少,焦点不明显。

退得太多,用户又会觉得页面突然换了一套界面。

好的状态应该是用户仍然知道“我还在原来的页面里”,只是当前操作对象更靠前。

9.3 动画是否连续

点击卡片、展开面板、关闭面板,这三个状态要来回跑几次。

尤其关注反向动画。

很多页面打开的时候很好看,一关闭就瞬间跳回原位,这种割裂感非常明显。

9.4 连续操作时是否掉帧

不要只点一次。

快速打开、关闭,多操作几轮,再观察动画是否稳定。

官方的动画性能指南也建议合理选择系统提供的属性动画、显式动画和图形变换能力,避免不必要的 UI 主线程负载。

9.5 用 ArkUI Inspector 看实际组件层次

最后再切到 Inspector。

这一步能把很多“肉眼看起来正常”的结构问题揪出来。

尤其是做了多个 Stack、浮层、透明层以后,3D 展开非常直观。


10. 空间化设计不是所有页面都必须做

讲到这里还得泼一点冷水。

不是每个页面都适合做空间化。

比如:

  • 登录页;
  • 简单设置页;
  • 单纯表单页;
  • 只有两三个选项的确认页;
  • 强调高效率输入的工具页面。

这些页面的核心目标是“赶紧完成任务”。

如果为了空间感加入过多层级、材质和动效,反而会降低效率。

真正适合空间化的,通常是这些场景:

内容有明确主次

比如媒体播放器、商品详情、设备控制、数据看板。

用户会围绕一个对象持续操作

例如照片、视频、设备、商品、任务卡片。

页面状态之间有明显上下文关系

用户需要知道“我从哪来、现在在操作谁、完成以后回到哪里”。

这种场景里,空间层级不仅是视觉效果,它实际上能帮助用户理解产品结构。


11. 从“平面布局”改到“空间层级”,我最大的感受

以前做页面,我们很容易把注意力放在尺寸上:

“这里 16vp。”

“那里圆角 24vp。”

“这个按钮往下挪 8vp。”

这些当然重要。

但空间化 UI 会迫使我们多问一个问题:

这个元素在用户当前任务里,到底应该站在前面还是后面?

一旦把这个问题想清楚,很多设计决定反而会更容易。

重要的信息不用再拼命加颜色,因为它可以通过位置和层级获得注意力。

次要信息也不用彻底隐藏,因为它可以自然退后。

交互状态不用每次都打开新页面,因为当前对象可以在原页面里被“提到前面”。

这其实是一种很朴素的设计逻辑。

就像现实生活里,我们拿起一本书的时候,书会离眼睛更近,桌面上的其他东西自然变成背景。我们不需要有人告诉我们“现在请重点关注这本书”,空间关系本身已经把信息说清楚了。

HarmonyOS 7 把空间感、沉浸光感和更丰富的交互表达继续往前推进,对应用开发者来说,真正值得关注的并不是“以后是不是所有页面都要做成 3D”。

而是:

我们终于可以少依赖一点颜色、边框和字号,开始用空间关系本身组织信息。

请添加图片描述

12. 最后总结

回头看这次改造,其实没有什么特别玄学的东西。

核心就六步:

  1. 找到原平面页面的问题;
  2. 重新梳理信息优先级;
  3. 把页面拆成背景、基础内容、核心内容、当前交互和反馈几个层级;
  4. Stack 建立叠层关系;
  5. scaletranslateopacityanimateTo 表达前后变化;
  6. 最后在 DevEco Studio 和 ArkUI Inspector 里验证布局、遮挡、交互与动画性能。

真正要避免的反而是“为了空间化而空间化”。

如果一个阴影能解决问题,就没必要旋转。

如果一次轻微缩放能建立焦点,就没必要让整张卡片飞来飞去。

空间化 UI 的重点,不是把界面做得更花,而是让用户更快看懂主次关系。

这也是我觉得 HarmonyOS 7 空间化设计最值得开发者认真研究的一点。


参考资料

  1. 华为开发者联盟:HarmonyOS 7 新能力一览
    https://developer.huawei.com/consumer/cn/features/

  2. 华为开发者联盟:HarmonyOS 设计规范和指南
    https://developer.huawei.com/consumer/cn/design

  3. 华为开发者文档:优化动画性能
    https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-animation-usage-guide

  4. 华为开发者文档:ArkUI Inspector 布局分析
    https://developer.huawei.com/consumer/cn/doc/doccenter-deveco-studio/ide-arkui-inspector

  5. 华为开发者联盟:HarmonyOS 应用开发工具与平台
    https://developer.huawei.com/consumer/cn/develop/index.html

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐