HarmonyOS 6实战:用悬浮导航和沉浸光感做AI出行助手

0 阅读

HarmonyOS 6实战:用悬浮导航和沉浸光感做AI出行助手

HarmonyOS 6(API 23)带来了两个值得关注的新能力:悬浮导航和沉浸光感。它们不只是视觉上的升级,更给出行类应用提供了新的交互思路。我们尝试用这些特性做了一个叫“光语智行”的AI出行助手,把智能体的状态变化变成看得见的光效,同时用悬浮导航节省屏幕空间。

文章配图

悬浮导航在出行场景中的实际价值

传统出行App底部通常有个固定Tab栏,占地方不说,还容易遮挡地图内容。HarmonyOS 6的悬浮导航解决了这个问题:

  • 不抢地图空间:导航栏浮在内容上,地图能完整显示
  • 毛玻璃融合:背景模糊效果让导航和地图自然衔接
  • 自动调节透明度:滑动地图时导航变透明,减少干扰
  • MiniBar扩展:右边还能加个语音入口或进度条

我们在真机上测试发现,这种设计在小屏手机上尤其有用——地图可视区域多了差不多10%。

沉浸光感不只是装饰,而是状态语言

很多人以为光效就是炫技,但我们把它变成了智能体的“表情”。当AI在不同阶段工作时,界面会发出对应颜色和节奏的光:

  • 待机时:柔和蓝白光,3秒一次缓慢呼吸
  • 听你说话:淡紫色,1.5秒脉冲,表示正在理解
  • 算路线:琥珀色快闪,1秒一次,全力计算中
  • 出方案:青绿色高频闪烁,800毫秒周期
  • 完成任务:翠绿色确认闪光
  • 出问题:橙红色急促警示

用户反馈说,这种设计让他们感觉AI真的在“思考”,而不是冷冰冰地返回结果。

窗口沉浸配置的关键细节

要实现真正的全屏光效,得先搞定窗口设置。核心是这几步:

// EntryAbility.ets
private async setupImmersiveWindow(windowStage: window.WindowStage): Promise<void> {
  const mainWindow = windowStage.getMainWindowSync();
  
  // 内容延伸到状态栏和导航栏区域
  await mainWindow.setWindowLayoutFullScreen(true);
  
  // 背景透明,让光效能透出来
  await mainWindow.setWindowBackgroundColor('#00000000');
  
  // 系统栏也设成透明
  await mainWindow.setWindowSystemBarProperties({
    statusBarColor: '#00000000',
    navigationBarColor: '#00000000',
    statusBarContentColor: '#FFFFFF',
    navigationBarContentColor: '#FFFFFF'
  });
  
  // 启用安全区避让(HarmonyOS 6新增)
  await mainWindow.setWindowAvoidAreaOption({
    type: window.AvoidAreaType.TYPE_SYSTEM,
    enabled: true
  });
}

这里最关键的是 setWindowAvoidAreaOption,它能自动避开刘海屏或挖孔区域。之前版本需要手动计算安全区高度,现在系统直接处理了。

在这里插入图片描述

智能体光效系统的实现逻辑

在这里插入图片描述

我们用一个控制器类管理所有光效状态:

在这里插入图片描述

// AgentLightEffect.ets
export enum AgentState {
  IDLE, UNDERSTANDING, PLANNING, GENERATING, COMPLETED, WARNING
}

@Observed
export class AgentLightController {
  @Track currentState: AgentState = AgentState.IDLE;
  
  private stateLightMap: Map<AgentState, LightConfig> = new Map([
    [AgentState.IDLE, { primaryColor: '#E8F4FD', pulseDuration: 3000, ... }],
    [AgentState.UNDERSTANDING, { primaryColor: '#E0D4F7', pulseDuration: 1500, ... }],
    // 其他状态配置...
  ]);

setState(state: AgentState): void {
    this.currentState = state;
    this.startPulseAnimation(); // 启动对应动画
  }
}

UI组件监听这个控制器,自动更新颜色和动画参数。双层光晕设计(外层大范围模糊+内层核心光)让效果更有层次,不会糊成一片。

悬浮导航的完整实现

导航栏本身是个带毛玻璃效果的容器,里面包含出行模式页签和MiniBar:

// AgentFloatNavigation.ets
build() {
  Stack({ alignContent: Alignment.Bottom }) {
    // 内容区域
    Column() { this.contentBuilder() }
      .padding({ bottom: this.bottomAvoidHeight + 90 })
    
    // 悬浮导航容器
    Column() {
      // 毛玻璃背景
      Column()
        .backgroundBlurStyle(BlurStyle.REGULAR)
        .backdropFilter($r('sys.blur.20'))
      
      // 出行模式页签
      Row() {
        ForEach(this.travelModes, (item, index) => {
          Column() {
            Image(item.icon).fillColor(this.currentIndex === index ? item.color : '#888888')
            Text(item.label).fontColor(this.currentIndex === index ? item.color : '#AAAAAA')
            
            // 选中时的光晕指示器
            if (this.currentIndex === index) {
              Column()
                .backgroundColor(item.color + '33')
                .blur(8)
            }
          }.onClick(() => {
            this.currentIndex = index;
            this.lightController.setState(AgentState.PLANNING);
          })
        })
      }
      
      // MiniBar语音入口
      Column() {
        Image($r('app.media.ic_agent_avatar'))
          .border({ color: this.lightController.getCurrentConfig().secondaryColor })
        
        // 状态指示点
        Column()
          .backgroundColor(
            this.lightController.currentState === AgentState.IDLE ? '#4CAF50' :
            this.lightController.currentState === AgentState.WARNING ? '#FF5722' : '#FFC107'
          )
      }.onClick(() => {
        this.lightController.setState(AgentState.UNDERSTANDING);
      })
    }
    .gesture(LongPressGesture({ duration: 600 }).onAction(() => {
      this.isExpanded = !this.isExpanded; // 长按展开透明度调节
    }))
  }
}

长按导航栏还能展开透明度调节滑块,用户可以根据环境光调整毛玻璃强度。这个细节在强光下特别实用。

行程卡片的玻璃拟态设计

行程详情卡片用了更厚的模糊效果(BlurStyle.THICK),顶部还有个根据路况变色的光条:

  • 畅通:绿色光条+绿色阴影
  • 缓行:黄色光条
  • 拥堵:红色光条
// TripCard.ets
build() {
  Stack() {
    // 厚毛玻璃背景
    Column()
      .backgroundBlurStyle(BlurStyle.THICK)
      .backdropFilter($r('sys.blur.40'))
    
    // 路况光效条
    Column()
      .backgroundColor(this.trafficColorMap.get(this.tripInfo.trafficStatus) || '#4CAF50')
      .shadow({
        color: (this.trafficColorMap.get(this.tripInfo.trafficStatus) || '#4CAF50') + '66'
      })
    
    // 卡片内容...
  }
}

实测发现,backdropFilter($r('sys.blur.40')) 比单纯用 backgroundBlurStyle 效果更细腻,但要注意性能——在低端机上可能需要降级。

语音交互页面的沉浸感营造

全屏语音页面做了三件事来增强沉浸感:

  1. 深色背景:用 #0A0A1A 减少视觉干扰
  2. 动态环境光晕:大范围模糊光随状态变化
  3. 状态可视化:处理过程中显示光效+文字提示
// VoiceChatPage.ets
build() {
  Stack() {
    // 深色背景
    Column().backgroundColor('#0A0A1A')
    
    // 环境光晕
    Column()
      .backgroundColor(this.lightController.getCurrentConfig().primaryColor)
      .blur(150)
      .opacity(0.4)
      .position({ x: '50%', y: '30%' })
      .animation({ /* 呼吸动画 */ })
    
    // 对话内容...
  }
  .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}

.expandSafeArea 让内容真正延伸到屏幕边缘,配合状态栏白色文字,整体感觉更开阔。

主页面集成与数据流

最后把所有组件串起来:

// Index.ets
build() {
  AgentFloatNavigation({
    lightController: this.lightController,
    contentBuilder: this.MapContentBuilder.bind(this) // 注入地图内容
  })
}

@Builder
MapContentBuilder(): void {
  Stack() {
    // 模拟地图
    Column().backgroundColor('#1A1A2E')
    
    // 路线光效轨迹
    Column()
      .backgroundColor('#4CAF50')
      .blur(8)
      .shadow({ color: '#4CAF5066' })
    
    // 行程卡片
    TripCard({ tripInfo: this.tripInfo, lightController: this.lightController })
      .position({ y: 380 })
    
    // 语音悬浮按钮
    Stack() {
      Column().backgroundColor(this.lightController.getCurrentConfig().secondaryColor).blur(30)
      Image($r('app.media.ic_mic'))
    }.onClick(() => router.pushUrl({ url: 'pages/VoiceChatPage' }))
  }
}

这里用 @Builder 参数把地图内容注入悬浮导航组件,避免了父子组件的强耦合。

调试时踩过的坑

  1. 毛玻璃效果在模拟器上失真:必须用真机测试,尤其是不同厂商的OLED屏表现差异大
  2. 安全区高度获取时机:要在 aboutToAppear 里调用 getWindowAvoidArea,太早会拿不到值
  3. 光效性能问题:循环动画(iterations: -1)在页面不可见时要手动暂停,否则耗电
  4. 低版本兼容:API 22以下设备没有 barFloatingStyle,得回退到普通Tabs

总结

HarmonyOS 6的这两个新特性确实改变了出行App的设计思路:

  • 悬浮导航让地图空间更完整
  • 沉浸光感把AI状态变成可感知的视觉语言
  • 玻璃拟态组件与背景自然融合

最重要的是,这些不是孤立的功能,组合起来才能产生1+1>2的效果。比如悬浮导航的MiniBar点击后唤起语音页面,光效从导航栏延续到全屏环境光,整个体验是连贯的。

未来如果系统能开放更多光效控制权限(比如调节光晕扩散速度),交互可能性还会更大。不过目前这套方案已经能在支持HarmonyOS 6的设备上跑起来了,核心代码量其实不大,关键在于把状态和视觉元素做精准映射。