灶台菜谱设计手记 05|HarmonyOS 7.0 空间化:玻璃效果实现【鸿蒙心迹】

1. 前言
番茄炖牛腩进入小火炖煮阶段。用户除了阅读步骤,还可以播放一段本地视频,看看锅里的翻滚程度。底部MiniBar仍显示当前步骤,并提供返回入口。页面结构没有大变,但材质背后的内容开始持续变化。
这让一个容易被忽略的问题浮现出来:玻璃区域看起来不大,维护它的开销是否也很小?
沉浸光感材质的折射和模糊需要采样背后的内容,覆盖视频时会随动态背景重新计算。这是检查布局的理由,却还不足以告诉我们,灶台菜谱上的哪一块材质值得移除。

图05-D:在同一烹饪页标出视频区域、底部材质和当前步骤文字,观察背景变化与材质覆盖的关系。
前四篇依次处理了作用域、文字、反馈和布局。本篇继续使用番茄炖牛腩、“备菜、烹饪、笔记”三个页签,以及同一份RecipeData和currentStep。MiniBar负责摘要与返回,“下一步”负责推进;视频结束不会替用户确认一道烹饪操作。
这篇要回答的问题是:哪些效果帮助用户理解界面,哪些只是增加了重算和绘制成本?回答它需要两类证据:呈现的成本,以及用户任务是否仍然成立。
2. 方案
我会先改变结构,再调整材质参数。结构对照更容易解释:视频与底栏有没有重叠,通常比某个颜色参数改变了多少更清楚。
| 方案 | 安排 | 比较目的 |
|---|---|---|
| A | 视频延伸到底部材质背后 | 建立动态重叠基线 |
| B | 保留底栏材质,将同尺寸视频放到材质区域之外 | 与A比较重叠关系 |
| C | 保留A的视频位置和底栏尺寸,关闭被测底栏材质,使用实色背景 | 与A比较材质与实色呈现 |
这里的底栏沿用已有布局。HDS悬浮导航与普通组件分别遵守各自的配置方式,不能为了得到一块玻璃,把普通正文容器当成支持材质的区域。

图05-A:三幅剖面使用相同的视频显示尺寸和底栏尺寸,分别标出动态区域、材质区域及其交集。
A和B保持材质配置、面积、阴影和文字一致。B调整位置时不缩小视频,也不额外裁切。如果某个窗口放不下同尺寸画面,就为这个窗口单独建立记录。缩小画面后再宣称避让有效,会混入另一个解释。
C也需要谨慎。覆盖一层不透明背景只能说明材质看不见,不能证明相关配置已经关闭。应沿组件树检查底栏与子节点,使用对应接口的关闭方式,并保持其他区域不变。普通组件的undefined表示恢复默认,不能用它代替明确关闭。
三个方案都播放同一文件、同一区间,固定播放速率、音频设置和缩放方式。静态菜图适合交代场景,但图片与视频的总开销差异还包含播放和解码成本,不能全部记到材质账上。
关键步骤文字继续放在稳定背景上。A允许装饰性画面延伸到底栏后面,不允许遮住步骤正文或“下一步”。否则我们比较的已经是两种不同的可用程度。
3. 实现
实现时,我先把播放状态和菜谱状态分开。这两个状态看起来总在一起,变化原因却不同:暂停可能来自切换页签,步骤推进则必须来自有效操作。
下面用应用侧的转换函数表达这条边界。它返回一个新的状态,播放器的暂停动作由调用方执行。
interface CookingState {
currentStep: number;
selectedTab: number;
playing: boolean;
}
function leaveCooking(
state: CookingState,
nextTab: number
): CookingState {
return {
currentStep: state.currentStep,
selectedTab: nextTab,
playing: false
};
}
function videoEnded(state: CookingState): CookingState {
return {
currentStep: state.currentStep,
selectedTab: state.selectedTab,
playing: false
};
}
这两个函数都没有调用handleNext。离开烹饪页时暂停,返回后由用户恢复;开始一轮性能采样前,再统一定位到约定的视频起点。本地视频只对应“小火炖煮”,推进到其他步骤后,不应继续把它标作当前步骤的演示。
接下来为材质建立一份清单。仅搜索systemMaterial还不够,HDS配置、背景模糊、阴影和运行中的参数更新都需要检查。我会给每个区域一个稳定ID,让代码修改、测量记录和最终决定能够互相对应。
| 区域 | 用户任务 | 重点检查 |
|---|---|---|
| R01 标题栏 | 识别菜谱与进入原有菜单 | 实际面积、背景与阴影 |
| R02 底部导航 | 在三个页签间移动 | 动态重叠、材质配置与子节点 |
| R03 MiniBar | 辨认并返回当前步骤 | 摘要裁切、层次与参数更新 |
| R04 烹饪操作区 | 执行“下一步” | 作用域、反色范围与反馈 |
清单还要记录节点路径、接口体系、尺寸及单位、材质层次和证据编号。面积与层数分开看:两个重叠区域的面积直接相加,并不等于屏幕上的实际覆盖面积。
本系列使用HarmonyOS 7/API 26的普通组件沉浸光感适配。HDS沿用第04篇的ADAPTIVE类型与等级;uiMaterial的系统档位则不能由应用强制设置。THIN是uiMaterial的样式,也不能填进HDS的等级字段。
对于普通组件,材质配置应集中在已确认支持的局部区域。下面是使用自定义阴影时的配置片段,挂接位置沿用前篇的底部TabBar作用域。
import { uiMaterial } from '@kit.ArkUI';
// 支持区域内的局部容器属性
.systemMaterial(new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.THIN,
colorInvert: true,
applyShadow: false
}))
.shadow({ radius: 12, color: '#24000000' })
这里先关闭材质自带阴影,再使用自定义shadow。如果使用默认阴影,则保留applyShadow并移除自定义配置。两种策略选一种即可;属性数量本身不能证明GPU多执行了几次绘制。
反色仍受第2篇的设备、样式和资源颜色条件约束。缩小反色范围时,要检查文字所在的实际子树,不能为了减少参与节点,把需要保持可读的文字排除出去。
随后检查重复处理。材质已包含背景模糊,启用材质的同一路径上应审查backgroundBlurStyle和backgroundEffect。回退分支中的背景可能仍然有用,不能搜索到一个属性就全部删除。父子节点重复设置材质也一样:先确认生效关系,再保留必要的一层,不随意修改HDS组件内部结构。
最后查更新来源。视频每前进一帧,并不意味着底栏颜色也应该更新。避免将播放进度绑定到materialColor,或为装饰效果频繁增删材质子节点。当前步骤文字仍须正常更新;“保持稳定”不应成为冻结业务状态的理由。
已有“切换菜谱”菜单另做尺寸检查。主播放采样时保持它关闭,避免将弹层动画混进底栏实验,也不需要为此新增一个全屏弹窗。
4. 检验
我会把性能采样与功能回归分开。前者需要稳定场景,后者需要主动制造变化。边播放边查盐、旋转和连续点击,会得到一段热闹的轨迹,却很难说明是哪项变化导致了差异。
先在同一设备上固定构建模式、系统与SDK、亮度、刷新率设置、光感设置、主题、窗口和字体。记录电源状态、后台负载及初始设备状态,约定预热方式、采样时长与重复次数。运行顺序轮换,避免总让某个方案排在设备状态已经改变之后。
每轮都进入同一烹饪步骤、同一滚动位置,从同一视频时间点开始。素材标识、编码、分辨率、帧率和显示尺寸随记录保存。手机和平板分别比较,不把两台设备的绝对数值放在一起判胜负。
| 记录组 | 字段 |
|---|---|
| 身份 | 运行ID、工程版本、设备、OS/SDK、工具版本 |
| 场景 | 方案、区域ID、视频标识与区间、窗口、currentStep |
| 条件 | 亮度、刷新率、光感设置、预热与采样时长、重复序号 |
| 观察 | 帧耗时序列、卡顿定义与次数、可取得的GPU指标 |
| 证据 | 原始轨迹、截图位置、异常及排除理由、体验检查 |
拿到轨迹以后,先确认指标含义。视频源帧率不等于应用UI帧率,GPU总体利用率也不能直接拆成材质开销。帧耗时应保留分布和时间变化,卡顿阈值则要结合刷新条件解释。只给一个平均值,可能藏住用户能感知的短时停顿。
功耗单独测量,写清工具、采样范围以及功率或能量单位。帧耗时下降并不能自动推出省电;缺少功耗记录时,这一列保持空缺,不能填0。
结构比较完成后,再在固定结构上做单项修改。
| 版本 | 相对共同基线的唯一改动 | 配套检查 |
|---|---|---|
| E01 | 移除实际存在的重复模糊 | 回退背景仍可读 |
| E02 | 移除实际存在的材质嵌套 | 信息层级仍清楚 |
| E03 | 停止无必要的参数更新 | 摘要与反馈仍更新 |
| E04 | 缩小一个指定材质区域 | 文字不裁切、入口可触达 |
| F01 | 组合经检查保留的修改 | 完整任务回归 |

图05-B:单项版本分别连接同一基线,综合版本单独列出;每条记录关联唯一改动、运行ID、观测量和体验检查。
E02不能在E01上继续改,然后把两项变化的差异都归给去嵌套。各单项版本从共同基线派生,综合版本才组合修改。某项问题不存在,就标“不适用”,不必为了让表格完整而制造缺陷。
我也会保留没有明显差异的记录。如果组间变化没有超出重复运行的波动,合理的结论就是当前条件不足以支持排序。先检查材质是否生效、C是否仍有残留材质、视频尺寸是否变化,再决定是否需要补充采样。
5. 结尾
玻璃效果值得保留的前提,是它承担了可解释的任务。MiniBar帮助用户找回当前步骤,底部导航帮助用户识别页面边界;如果某层效果没有增加这种信息,却扩大动态覆盖或引入无意义的更新,它就是优先检查的对象。
最终我会逐区域填写“保留、缩小、移除”的决定,同时附上实验ID、测量证据和体验代价。证据不足的项继续待定。材质预算也由这些具体区域组成:允许在哪里出现、多大、几层、因为什么更新,而非一个适用于所有应用的面积百分比。

图05-C:将各方案的测量证据与文字、反馈、末行检查并列;帧耗时以ms表示,独立功耗另设面板,各项关联原始记录。
交付前还要走回用户的厨房任务。
| 检查 | 应保持的结果 |
|---|---|
| 浅深主题、固定菜图与播放视频 | 摘要、“下一步”和正文均可读 |
| 按下拖出、禁用、关闭光效 | 取消与禁用不推进,关闭光效后仍能操作 |
| 正常与连续有效点击 | 每次推进一项,在末步停止,显示“已到最后一步” |
| 烹饪→备菜查盐→末行→MiniBar返回 | 用量来自同一数据,末行无遮挡,返回原currentStep |
| 笔记页返回、旋转、大字体、折叠与展开 | 入口可达,布局变化不重置进度 |
| 视频暂停、结束、离页与返回 | 播放状态不代替步骤完成 |
这留下四份可继续使用的资产:材质区域审计表、单变量实验模板、原始测量字段表和系列最终回归清单。它们通过同一套区域ID与运行ID连接,后续调整时可以找到原先的理由。
五篇文章从“材质在哪里生效”走到“哪些材质值得留下”,判断标准始终落在同一个动作上:用户抬眼读清当前步骤,找到入口,然后继续做菜。性能优化的价值,也要在这个动作仍然顺畅时才能成立。
更多推荐




所有评论(0)