【OpenHarmony/HarmonyOs 】沉浸式全屏 Header 与安全区适配:让学习页面更有空间感

本文基于我的 OpenHarmony/HarmonyOS 项目「物理视界 PhysicsVision」整理。项目中多个页面都采用了沉浸式顶部 Header:实验室、挑战、成就、收藏、设置都有独立的渐变头部和安全区适配。
这一篇单独聊:如何做全屏布局、如何处理状态栏安全区、如何让 Header 既好看又不遮挡内容。📱

一、什么是沉浸式 Header?

沉浸式 Header 的核心不是“把状态栏盖住”,而是让页面顶部视觉自然延伸到系统状态栏区域。

普通页面可能是这样:

  • 状态栏一块颜色;
  • 页面 Header 一块颜色;
  • 中间有明显割裂。

沉浸式页面则希望:

  • Header 背景延伸到顶部;
  • 状态栏区域和页面融为一体;
  • 内容从安全区域下方开始;
  • 不遮挡文字和按钮。

在「物理视界」中,每个主模块都有一个主题色 Header:

  • 实验室:蓝色科技感;
  • 挑战:橙色活力感;
  • 成就:金色激励感;
  • 收藏:粉色温暖感;
  • 设置:紫色品牌感。

这种处理能让用户进入不同模块时马上建立场景感。

二、入口 Ability 中开启全屏布局

项目在 EntryAbility.ets 中设置了窗口全屏布局:

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.getMainWindow().then((win: window.Window) => {
    win.setWindowLayoutFullScreen(true)
  }).catch((err: Object) => {
    hilog.error(DOMAIN, 'testTag', 'Failed to set full screen. Cause: %{public}s', JSON.stringify(err))
  })

  windowStage.loadContent('pages/Index', (err) => {
    if (err.code) {
      hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err))
      return
    }
    hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.')
  })
}

setWindowLayoutFullScreen(true) 让应用内容可以布局到系统状态栏区域。
但注意:开启全屏只是第一步,后续页面还必须自己处理安全区。

三、安全区适配:expandSafeArea

以实验室首页为例,Header 这样处理:

.padding({ left: 20, right: 20, top: 60, bottom: 16 })
.linearGradient({
  angle: 135,
  colors: [['#1A73E8', 0], ['#1565C0', 0.5], ['#0D47A1', 1]]
})
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])

这里有两个细节:

  1. padding.top 给内容留出空间,避免文字顶到状态栏;
  2. expandSafeArea 让背景扩展到顶部安全区。

如果只有 padding.top,背景不一定能覆盖状态栏。
如果只有 expandSafeArea,内容又可能太靠上。
两者结合,才能既沉浸又安全。

四、实验室 Header:学习进度和随机探索

实验室页的 Header 不只是标题,它还放了学习进度和随机探索入口:

Row() {
  Column({ space: 3 }) {
    Text('物理视界')
      .fontSize(26)
      .fontWeight(FontWeight.Bold)
      .fontColor('#FFFFFF')
    Row({ space: 6 }) {
      Text('已探索')
      Text(this.getVisitedCount().toString() + '/' + this.names.length.toString())
      Text('·')
      Text('收藏 ' + this.getFavCount().toString())
    }
  }

  Blank()

  Column() {
    Text('🎲').fontSize(18)
  }
  .width(42)
  .height(42)
  .backgroundColor('rgba(255,255,255,0.15)')
  .borderRadius(12)
  .onClick(() => {
    this.navigateToRandom()
  })
}

这让 Header 承担了三个功能:

  • 告诉用户在哪里;
  • 展示当前学习进度;
  • 提供随机探索入口。

相比只写一个标题,这种 Header 更像“学习仪表盘”。

五、进度条:让学习目标可视化

实验室 Header 中还显示了已探索进度:

Stack({ alignContent: Alignment.Start }) {
  Row()
    .width('100%')
    .height(4)
    .backgroundColor('rgba(255,255,255,0.15)')
    .borderRadius(2)
  Row()
    .width(this.getProgressPercent().toString() + '%')
    .height(4)
    .backgroundColor('#FFD93D')
    .borderRadius(2)
}

getProgressPercent 根据已访问模型数量计算:

getProgressPercent(): number {
  return Math.round(this.getVisitedCount() / this.names.length * 100)
}

这是一个很适合学习 App 的设计:
用户不需要打开成就页,也能在首页看到自己学到了哪里。

六、不同模块使用不同主题色

挑战页 Header 使用橙色渐变:

.linearGradient({
  angle: 135,
  colors: [['#FF6D00', 0], ['#F4511E', 1]]
})

收藏页 Header 使用粉色渐变:

.linearGradient({
  angle: 135,
  colors: [['#E91E63', 0], ['#C2185B', 0.5], ['#AD1457', 1]]
})

成就页 Header 使用金色渐变:

.linearGradient({
  angle: 135,
  colors: [['#FFD700', 0], ['#FF9800', 0.5], ['#FF6D00', 1]]
})

同样的布局,不同的主题色,能形成清晰模块区分。
用户切换页面时,不用读很多文字,也能知道当前在哪个功能区。

七、Header 动画:轻微缩放和淡入

每个模块都设置了 Header 入场动画:

@State headerAnim: boolean = false

aboutToAppear(): void {
  setTimeout(() => {
    animateTo({ duration: 600, curve: curves.springCurve(0, 1, 328, 28) }, () => {
      this.headerAnim = true
    })
  }, 100)
}

UI 上使用:

.scale({ x: this.headerAnim ? 1 : 0.95, y: this.headerAnim ? 1 : 0.95 })
.opacity(this.headerAnim ? 1 : 0)

这个细节很小,但能明显提升质感。
它不像大面积动画那么夸张,只是让页面从“突然出现”变成“轻轻进入”。

八、沉浸式布局的注意点

做沉浸式 Header 时,我总结了几个注意点:

  1. 不要只开启全屏,必须配合安全区;
  2. Header 内容顶部要有足够 padding;
  3. 背景要延伸到状态栏区域;
  4. 浅色 Header 注意状态栏图标可读性;
  5. 不同页面最好有主题差异;
  6. 顶部按钮尺寸要足够,不要贴边;
  7. 页面滚动内容要和 Header 有明确层次。

如果这些细节没处理好,沉浸式布局很容易变成“遮挡式布局”。

九、适合继续优化的方向

后续可以继续做:

  • 根据系统深色模式切换 Header 渐变;
  • 滚动时让 Header 高度收缩;
  • 平板横屏时改为左侧标题区;
  • 加入背景动效,例如轻微粒子或物理轨迹;
  • 让 Header 与当前分类颜色联动。

总结

沉浸式 Header 是提升应用质感的高性价比细节。
在 OpenHarmony/HarmonyOS ArkUI 中,只要处理好 setWindowLayoutFullScreenexpandSafeArea、padding 和背景,就能做出比较完整的全屏页面体验。

「物理视界」里每个主模块都有独立 Header,这让学习 App 不再只是列表集合,而是更像一个有空间感的数字物理实验室。✨

img

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐