在鸿蒙元服务开发中,ASCF 导航栏的动态设置看起来只是调用两个 API,但实际使用时有几个细节容易踩坑。官方提供了 has.setNavigationBarTitle 和 has.setNavigationBarColor,分别用来修改标题和颜色。静态配置导航栏是在 app.json 的 window 字段里写死,整个应用共用一套配置;如果在每个页面的 json 里单独写 window,也只能在页面加载时固定,运行时无法修改。ASCF 的动态 API 可以在代码里随时调整。
基础用法上,改标题的调用结构如下:
- has.setNavigationBarTitle({
- title: '当前页面',
- success: () => {
- console.info('setNavigationBarTitle success');
- },
- fail: (err) => {
- console.error('setNavigationBarTitle fail', err);
- }
- });
复制代码
改颜色的结构类似:
- has.setNavigationBarColor({
- frontColor: '#000000',
- backgroundColor: '#ff0000',
- success: () => {
- console.info('setNavigationBarColor success');
- },
- fail: (err) => {
- console.error('setNavigationBarColor fail', err);
- }
- });
复制代码
这两个 API 的参数都是 Object 类型,带 success、fail、complete 回调,并且都是异步执行。
接下来是几个必须注意的限制。
第一,frontColor 只能填 #000000 或 #FFFFFF。它控制的是前景色,也就是标题文字和按钮的颜色,设计目的是区分深色/浅色前景,不是用来自定义任意颜色。如果填了 #FFFF00 想设置黄色标题,会直接报错。另外还有版本差异:HarmonyOS API 12 只有在 window 配置了 navigationStyle = "custom" 时才能设置 #FFFFFF,其他情况强制 #000000;HarmonyOS API 13+ 黑白都能自由设置。如果项目需要兼容老版本,必须留意 SDK 版本,或者统一用 #000000 最安全。
第二,setNavigationBarTitle 的 title 字段必填。不传 title 会直接走 fail 回调。例如下面这样不行:
- // 这样不行,title 不传会 fail
- has.setNavigationBarTitle({
- success: () => { console.info('success'); },
- fail: (err) => { console.error('fail', err); }
- });
复制代码
第三,backgroundColor 要合法的十六进制颜色值。背景色可以填十六进制,但格式必须正确。如果是从配置里动态读取颜色值,记得先做格式校验,避免出现非法字符串导致调用失败。
实际开发中,动态设置导航栏有几个典型场景。
场景一,根据数据状态动态改标题。比如详情页的标题要等数据加载后才能确定:
- Page({
- data: {
- itemTitle: ''
- },
- onLoad() {
- this.loadDetail();
- },
- loadDetail() {
- // 模拟请求
- setTimeout(() => {
- const title = '商品详情 - iPhone 16';
- this.setData({ itemTitle: title });
- has.setNavigationBarTitle({
- title: title,
- fail: (err) => {
- console.error('设置标题失败', err);
- }
- });
- }, 500);
- }
- });
复制代码
数据回来之后顺手把标题设了,用户体验会更好,不会一直显示一个笼统的“详情页”。
场景二,主题色切换。做深色模式或自定义主题时,导航栏颜色需要跟着切换:
- Page({
- data: {
- isDark: false
- },
- toggleTheme() {
- const isDark = !this.data.isDark;
- this.setData({ isDark });
- has.setNavigationBarColor({
- frontColor: isDark ? '#ffffff' : '#000000',
- backgroundColor: isDark ? '#1a1a1a' : '#ffffff',
- });
- }
- });
复制代码
这里前景色跟着黑白切换,背景色也对应调整。
场景三,页面跳转后恢复默认。这里有一个容易忽略的坑:用 setNavigationBarColor 改了颜色后,跳转到新页面时颜色不会自动恢复。如果新页面不需要自定义导航栏颜色,记得在 onShow 里重置:
- Page({
- onShow() {
- // 恢复默认导航栏颜色
- has.setNavigationBarColor({
- frontColor: '#000000',
- backgroundColor: '#ffffff',
- });
- }
- });
复制代码
否则用户可能会看到上一个页面的配色一直带过来。我一开始还以为是 bug,排查后才发现是状态没有清理。
排障方面,遇到过调了 setNavigationBarColor 但导航栏颜色没变的情况。排查发现是 frontColor 填了 #333333,不是合法的黑白值,整个调用直接 fail。因此建议在 fail 回调里一定要打日志,否则静默失败很难定位。API 版本差异也需要关注,如果兼容老版本,可以判断当前 SDK 版本,或者干脆统一用 #000000。
总的来说,导航栏动态设置本身不复杂,关键细节是:frontColor 只能黑白、title 必填、页面跳转后要手动恢复颜色。如果做的是自定义导航栏,也就是 navigationStyle = "custom",这套 API 就不管用了,需要走另外的方案。 |