【OpenHarmony/HarmonyOs 】物理模型详情页模板:返回、收藏、安全区、动效与参数面板统一设计

本文基于我的 OpenHarmony/HarmonyOS 项目「物理视界 PhysicsVision」整理。项目中 28 个物理模型虽然内容不同,但详情页结构很统一:顶部返回栏、收藏按钮、Canvas 实验区、播放控制、参数调节、数据面板和知识说明。
这一篇单独拆“模型详情页模板”,对应“全新视觉与交互体验”和“隐私友好的本地学习”的主题。📐

一、为什么需要统一的模型详情页模板?

物理模型很多,如果每个页面都用完全不同的布局,用户会很快迷路。

「物理视界」中有声音传播、自由落体、平抛运动、电场线、光的干涉、凸透镜成像等模型。它们的物理内容不同,但页面操作应该保持一致:

  • 左上角返回;
  • 右上角收藏;
  • 中间 Canvas 实验区;
  • 下方控制按钮;
  • 参数滑块;
  • 数据展示;
  • 知识解释。

统一模板可以让用户学会一次操作,就能迁移到所有模型。

二、顶部栏:返回 + 标题 + 收藏

以「光的干涉」页面为例:

Row() {
  Text('←')
    .fontSize(28)
    .fontWeight(FontWeight.Bolder)
    .fontColor($r('app.color.text_primary'))
    .onClick(() => router.back())

  Text('光的干涉 🌈')
    .fontSize(20)
    .fontWeight(FontWeight.Bolder)
    .fontColor($r('app.color.text_primary'))
    .margin({ left: 16 })

  Blank()

  Text(this.isFav() ? '❤️' : '🤍')
    .fontSize(22)
    .onClick(() => { this.toggleFav() })
}

这段结构几乎在多个模型页面中复用:

  • 返回按钮负责路由回退;
  • 标题告诉用户当前模型;
  • 收藏按钮记录学习重点。

这是一个很适合学习类 App 的详情页头部结构。

三、安全区适配:详情页也要沉浸但不遮挡

顶部栏统一使用:

.padding({ left: 20, right: 20, top: 48, bottom: 14 })
.backgroundColor($r('app.color.bg_card'))
.border({ width: { bottom: 2 }, color: $r('app.color.border_strong') })
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])

这里的设计考虑是:

  1. 顶部内容不会贴状态栏;
  2. 背景延伸到安全区;
  3. 底部边框让顶部栏和内容区分开;
  4. 深色模式下也能保持层次。

详情页不像首页那样使用大面积渐变 Header,而是使用更稳的卡片色顶部栏,方便用户专注实验本身。

四、收藏逻辑:每个模型都有自己的 modelIndex

每个模型页面都有自己的索引:

private modelIndex: number = 11
@StorageLink('favorites') favStr: string = ''

判断是否收藏:

isFav(): boolean {
  if (this.favStr.length === 0) return false
  let parts: string[] = this.favStr.split(',')
  for (let i = 0; i < parts.length; i++) {
    if (parseInt(parts[i]) === this.modelIndex) return true
  }
  return false
}

收藏切换:

toggleFav(): void {
  if (this.isFav()) {
    let parts: string[] = this.favStr.split(',')
    let np: string[] = []
    for (let i = 0; i < parts.length; i++) {
      if (parseInt(parts[i]) !== this.modelIndex) np.push(parts[i])
    }
    this.favStr = np.join(',')
  } else {
    this.favStr = this.favStr.length === 0 ? this.modelIndex.toString() : this.favStr + ',' + this.modelIndex.toString()
  }
}

这套逻辑让模型详情页和收藏页打通。
用户在详情页收藏后,可以在收藏页按分类快速找回。

五、Canvas 实验区:所有模型的视觉核心

模型详情页的主体通常是 Canvas:

Canvas(this.ctx)
  .width('100%')
  .height(340)
  .backgroundColor($r('app.color.bg_page'))
  .border({ width: 2, color: $r('app.color.border_strong') })
  .borderRadius(20)
  .onReady(() => {
    this.canvasReady = true
    this.drawScene()
  })
  .scale({ x: this.animCanvas ? 1 : 0.85, y: this.animCanvas ? 1 : 0.85 })
  .opacity(this.animCanvas ? 1 : 0)

这里有几个统一细节:

  • 边框强化实验台感觉;
  • 圆角让视觉更柔和;
  • onReady 后绘制;
  • 入场时缩放和淡入。

对物理学习来说,Canvas 就是“实验台”。

六、参数面板:滑块连接公式和画面

在光学、电磁学、力学模型中,参数面板大量使用 Slider:

Text(`波长 λ: ${this.wavelength.toFixed(0)} nm`)

Slider({ value: this.wavelength, min: 380, max: 700, step: 10 })
  .trackColor($r('app.color.slider_track'))
  .selectedColor(this.getColorFromWavelength())
  .onChange((v: number) => {
    this.wavelength = v
    if (this.canvasReady) this.drawScene()
  })

这种交互非常适合物理学习:

  • 参数变化看得见;
  • 公式结果实时更新;
  • Canvas 画面立即重绘;
  • 学生能主动探索变量关系。

七、数据面板:把现象落回公式

模型详情页通常会有数据展示,例如光的干涉:

Text('条纹间距 Δy')
Text(`${this.getFringeSpacing().toFixed(2)} mm`)
Text('Δy = λL/d')

凸透镜成像中则展示像距、像高、成像类型:

this.imageDist = v
this.imageHeight = -v / u * this.objectHeight
if (u > 2 * f) this.imageType = '倒立缩小实像'
else if (Math.abs(u - 2 * f) < 1) this.imageType = '倒立等大实像'
else if (u > f) this.imageType = '倒立放大实像'
else this.imageType = '正立放大虚像'

可视化负责吸引注意,数据面板负责建立理解。

八、动画入场:让页面更有层次

详情页通常有多段入场动画:

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

setTimeout(() => {
  animateTo({ duration: 600, curve: curves.springCurve(0, 1, 328, 28) }, () => {
    this.animParams = true
  })
}, 250)

Canvas、控制区、参数区、数据区分批出现。
这种节奏比所有内容瞬间出现更自然,也更符合“实验室”场景感。

九、本地优先:详情页不需要敏感权限

这些模型详情页都不需要:

  • 相机权限;
  • 相册权限;
  • 网络请求;
  • AI 识图;
  • 定位权限。

所有物理模拟都在端侧通过 Canvas 和公式完成。
这正好符合隐私保护主题:学习类 App 可以把核心体验做丰富,而不一定要依赖拍照、上传和云端识别。

十、总结

物理模型详情页的模板化设计,是「物理视界」能承载 28 个模型的重要原因。
统一顶部栏、统一收藏逻辑、统一 Canvas 实验区、统一参数面板和数据面板,让用户在不同模型间切换时不会重新学习操作。

这篇文章对应的主题是:全新视觉与交互体验 + 隐私友好的端侧学习
它体现了 OpenHarmony/HarmonyOS ArkUI 的一个优势:用统一组件结构和状态管理,把复杂知识点变成可交互的学习页面。✨

img

Logo

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

更多推荐