HarmonyOS 鸿蒙Next沉浸式效果

HarmonyOS 鸿蒙Next沉浸式效果 A,B两个页面,A页面没有设置沉浸式模式,B页面设置了沉浸式模式。在A页面跳转B页面时使用setWindowLayoutFullScreen()方法让页面变沉浸式,在B页面的aboutToDisappear生命周期中退出沉浸式,回到A页面,发现A页面也进入了沉浸式模式,怎么避免A页面因跳转B页面而进入沉浸式模式?

4 回复

【背景知识】

沉浸式模式通常指让应用的界面更加专注于内容,不希望用户被无关元素干扰。实现沉浸式效果有如下两种方案:

  • 窗口提供管理窗口的一些基础能力,包括对当前窗口的创建、销毁、各属性设置,以及对各窗口间的管理调度。其中,setWindowLayoutFullScreen用于动态设置主窗口或子窗口的布局模式为沉浸式,即隐藏系统状态栏/导航栏以最大化可用区域。
  • 设置组件的expandSafeArea属性,扩展组件的安全区域到状态栏和导航栏,从而实现沉浸式。

【解决方案】

由于aboutToDisappear生命周期是异步回调,因此在B页面的aboutToDisappear生命周期中退出沉浸式,A页面也会看到沉浸式过度为非沉浸式的效果。解决该问题可参考以下2种方案:

  • 方案一:在页面跳转过程中,通过页面生命周期方法动态控制沉浸式模式: 当B页面被隐藏时,在onPageHide方法种主动调用setWindowLayoutFullScreen(false)恢复非沉浸式状态,同时通过window.getLastWindow(getContext(this))确保仅操作当前页面的窗口实例,从而隔离页面间的状态影响,避免A页面因沉浸式模式被意外修改。

    A页面:

import { router } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('去第二个页面').onClick(() => {
        router.pushUrl({ url: 'pages/pageTwo' })
      })

    }.width('100%').height('100%').backgroundColor(Color.Red)
  }
}

B页面:

import { router, window } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  onPageShow(): void {
    window.getLastWindow(getContext(this), (err, win) => {
      win.setWindowLayoutFullScreen(true)
    })
  }

  onPageHide(): void {
    window.getLastWindow(getContext(this), (err, win) => {
      win.setWindowLayoutFullScreen(false)
    })
  }

  build() {
    Column() {
      Text('全屏页面....')
      Button('返回').onClick(() => {
        router.pushUrl({ url: 'pages/Index' })
      })
    }.width('100%').height('100%').backgroundColor(Color.Green)
  }
}
  • 方案二:使用expandSafeArea属性扩展安全区域的方案实现: 单个页面实现沉浸式,优先考虑使用expandSafeArea属性扩展安全区域的方案实现,该方案只会影响当前组件的布局。B页面示例代码为:
import { router } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('全屏页面....')
      Button('返回').onClick(() => {
        router.pushUrl({ url: 'pages/Index' })
      })
    }.width('100%').height('100%').backgroundColor(Color.Green)
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
  }
}

更多关于HarmonyOS 鸿蒙Next沉浸式效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


建议沉浸式不要一会开一会关,不好管理,不需要沉浸式的页面最外层组件加上上下padding或者占位组件。

鸿蒙Next的沉浸式效果通过系统级能力实现应用全屏显示,隐藏状态栏和导航栏。开发者使用UIAbilityWindow模块的setWindowSystemBarEnable方法控制系统栏显隐,结合onWindowStageCreate生命周期实现沉浸式布局。系统提供avoidAreaChange事件响应避免关键UI被遮挡,确保交互完整性。该效果适用于视频、游戏等全屏场景,由鸿蒙ArkUI框架直接支持,无需依赖外部技术栈。

在B页面退出沉浸式时,建议使用setWindowSystemBarEnable()方法而非setWindowLayoutFullScreen(false)。具体实现如下:

  1. 在B页面的aboutToDisappear生命周期中调用:
windowClass.setWindowSystemBarEnable(['status', 'navigation'])
  1. 同时确保在A页面跳转B页面时,仅使用setWindowLayoutFullScreen(true)设置B页面沉浸式,不要修改A页面的状态栏设置。

这种做法的原理是:setWindowSystemBarEnable()直接控制系统栏的显示状态,而不会影响窗口的布局模式。当B页面销毁时,系统会自动恢复A页面的原始系统栏状态。

注意在代码中提前通过getLastWindow()获取windowClass实例,并在B页面初始化时设置沉浸式模式。这样能确保页面切换时系统栏状态正确隔离。

回到顶部