首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >HarmonyOS NEXT实战:窗口沉浸式效果

HarmonyOS NEXT实战:窗口沉浸式效果

原创
作者头像
中雨
发布2025-06-28 14:32:10
发布2025-06-28 14:32:10
2510
举报
文章被收录于专栏:HarmonyOS NEXT实战HarmonyOS NEXT实战

##HarmonyOS Next实战##HarmonyOS SDK应用服务##教育##

参考资料:

https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-immersive

沉浸式效果概述

沉浸式模式通常指让应用的界面更加专注于内容,不希望用户被无关元素干扰。在移动端应用中,全屏窗口元素包括状态栏、应用界面和导航栏(如下图),沉浸式页面开发常通过将应用页面延伸到状态栏和导航栏的方式,来达到以下目的:

  • 使页面和避让区域的色调统一,为用户提供更好的视觉体验。
  • 最大程度利用屏幕可视区域,使页面获得更大的布局空间。
  • 提供完全沉浸的体验,让用户沉浸其中,不被其他事物所干扰。

实现沉浸式效果的两种方案

方案一:设置窗口全屏模式

方案二:扩展组件安全区域

推荐使用方案一,好处是可以针对整个应用(所有页面)实现沉浸式效果。

接口

代码语言:typescript
复制
setWindowLayoutFullScreen(isLayoutFullScreen: boolean): Promise<void>
  • 设置主窗口或子窗口的布局是否为沉浸式布局,使用Promise异步回调。从API version 14开始,该接口在2in1设备或平板设备的自由多窗模式(可点击设备控制中心中的自由多窗按钮开启)下调用不生效。
  • 沉浸式布局生效时,布局不避让状态栏与底部导航区域,组件可能产生与其重叠的情况。
  • 非沉浸式布局生效时,布局避让状态栏与底部导航区域,组件不会与其重叠。

前提:

窗口提供管理窗口的一些基础能力,包括对当前窗口的创建、销毁、各属性设置,以及对各窗口间的管理调度。

该模块提供以下窗口相关的常用功能:

Window:当前窗口实例,窗口管理器管理的基本单元。

WindowStage:窗口管理器。管理各个基本窗口单元。

以下是实现沉浸式效果的实战代码:

代码语言:typescript
复制
import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct SetFullWindowPage {
  @StorageProp('topRectHeight')
  topRectHeight: number = 0;
  @StorageProp('bottomRectHeight')
  bottomRectHeight: number = 0;

  build() {
    Column({ space: 10 }) {
      Text('SetFullWindow Page')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      Text(`topRectHeight = ${this.topRectHeight}`)
      Text(`bottomRectHeight = ${this.bottomRectHeight}`)

      Button('SetFullWindow')
        .onClick(() => {
          this.setFullWindow(true)
        })
      Button('CancelFullWindow')
        .onClick(() => {
          this.setFullWindow(false)
        })
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#cccccc')
    .padding({ top: this.topRectHeight, bottom: this.bottomRectHeight })
  }

  async setFullWindow(isLayoutFullScreen: boolean = true) {
    let context = getContext(this) as common.UIAbilityContext;
    let windowClass = await window.getLastWindow(context);
    // 1. 设置窗口全屏
    windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
      console.info('Succeeded in setting the window layout to full-screen mode.');
    }).catch((err: BusinessError) => {
      console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
    });
    // 2. 获取布局避让遮挡的区域
    let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
    let avoidArea = windowClass.getWindowAvoidArea(type);
    let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度
    AppStorage.setOrCreate('bottomRectHeight', px2vp(bottomRectHeight));
    type = window.AvoidAreaType.TYPE_SYSTEM; // 以状态栏避让为例
    avoidArea = windowClass.getWindowAvoidArea(type);
    let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
    AppStorage.setOrCreate('topRectHeight', px2vp(topRectHeight));

    // 3. 注册监听函数,动态获取避让区域数据
    windowClass.on('avoidAreaChange', (data) => {
      if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
        let topRectHeight = data.area.topRect.height;
        AppStorage.setOrCreate('topRectHeight', px2vp(topRectHeight));
      } else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
        let bottomRectHeight = data.area.bottomRect.height;
        AppStorage.setOrCreate('bottomRectHeight', px2vp(bottomRectHeight));
      }
    });
  }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档