在鸿蒙(HarmonyOS)中,沉浸式模式通常指的是让应用的界面更加专注于内容,隐藏系统状态栏和导航栏,以提供更加沉浸的用户体验。这种模式特别适用于游戏、视频播放、阅读等场景,其中用户可能不希望被界面元素干扰。
没有沉浸式模式的效果:
以下是如何在鸿蒙应用中实现沉浸式模式的一些基本步骤:
- 某个页面要突破
手机安全区域
来全屏显示(沉浸式模式显示
),其他页面不需要 - 在组件的aboutToAppear中使用
window
模块的getLastWindow
和setWindowLayoutFullScreen
两个方法来处理全屏显示
比如在"我的"页面:
ts
import { window } from '@kit.ArkUI'
@Component
export struct Mine {
aboutToAppear(): void {
window.getLastWindow(getContext()).then(win=>{
win.setWindowLayoutFullScreen(true) // 开启了当前页面的沉浸式模式(开启全屏模式)
})
}
build() {
Column(){
Text('我的' + Math.random().toFixed(2))
}
.height('100%')
.width('100%')
.backgroundColor(Color.Pink)
}
}
设置沉浸式模式的特点:
在任何一个页面中设置过一次之后,其他页面也会跟着全屏显示。
以上这么处理会出现问题: 从其他tab标签进入我的tab标签时,会出现底部tab栏闪动。
解决这种问题: 在进入应用时(index.tes页面)就开启所有页面的全屏模式。
但是又会带来新的问题:不需要全屏显示的其他页面的内容会突破安全区域显示,导致内容显示不正常
比如:
"首页"页面出现问题:内容突破了整个安全区域,靠手机顶部显示了内容
解决办法:
需要通过获取手机的安全高度来结合 padding来适配顶部内容的正常显示
步骤:
- 通过
window
模块的getLastWindow
和getWindowAvoidArea
来获取安全高度 - 安全高度获取到的是px单位,需要使用px2vp函数转换成vp单位
- 将安全区域高度保存到AppStorage中共享给其他页面使用
以下是Index页面的ArkTS代码
ts
import { Home } from '../views/home/home'
import { Interview } from '../views/interview/interview'
import { Mine } from '../views/mine/mine'
import { Project } from '../views/project/project'
import { window } from '@kit.ArkUI'
import { Logger } from '../common/utils/Logger'
@Entry
@Component
struct Index {
@State
currentIndex: number = 0
aboutToAppear(): void {
window.getLastWindow(getContext()).then(win => {
win.setWindowLayoutFullScreen(true)
let area = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM)
let height = area.topRect.height
let vpheight = px2vp(height)
AppStorage.setOrCreate('topHeight', vpheight)
Logger.info(height.toString(), vpheight.toString())
})
}
@Builder
tabBuilder(text: string, icon: ResourceStr, selectedIcon: ResourceStr, index: number) {
Column() {
Image(this.currentIndex === index ? selectedIcon : icon)
.height(28)
.aspectRatio(1)
Text(text)
}
}
build() {
Tabs({ index: $$this.currentIndex }) {
TabContent() {
if (this.currentIndex === 0) {
Home()
}
}
.tabBar(this.tabBuilder('首页', $r('app.media.home'), $r('app.media.home_select'), 0))
TabContent() {
if (this.currentIndex === 1) {
Project()
}
}
.tabBar(this.tabBuilder('项目', $r('app.media.tabbar_project'), $r('app.media.project_select'), 1))
TabContent() {
if (this.currentIndex === 2) {
Interview()
}
}
.tabBar(this.tabBuilder('面经', $r('app.media.tabbar_interview'), $r('app.media.interview_select'), 2))
TabContent() {
if (this.currentIndex === 3) {
Mine()
}
}
.tabBar(this.tabBuilder('我的', $r('app.media.tabbar_mine'), $r('app.media.mine_select'), 3))
}
.padding({ bottom: 15 })
.barPosition(BarPosition.End)
.animationDuration(0)
}
}
其他页面使用:
比如首页
ts
@Component
export struct Home {
@StorageProp("topHeight") topHeight: number = 0
build() {
Column() {
Text('首页' + Math.random().toFixed(2))
}
.padding({ top: this.topHeight })
.width("100%")
.height("100%")
.backgroundColor(Color.Gray)
}
}
实现效果:
可以看见,首页的内容区域是没有显示在安全区域了
设置安全区域文字颜色
- 通过
window
模块的getLastWindow
和setWindowSystemBarProperties({statusBarContentColor:颜色})
来设置安全区域文字颜色
ts
import { window } from '@kit.ArkUI'
@Component
export struct Mine {
@StorageProp("topHeight") topHeight: number = 0
aboutToAppear(): void {
window.getLastWindow(getContext()).then((win) => {
win.setWindowSystemBarProperties({ statusBarContentColor: '#FFFFFF' })
})
}
aboutToDisappear(): void {
window.getLastWindow(getContext()).then((win) => {
win.setWindowSystemBarProperties({ statusBarContentColor: '#000000' })
})
}
build() {
Column() {
Text('我的' + Math.random().toFixed(2))
}
.padding({ top: this.topHeight })
.width("100%")
.height("100%")
.backgroundColor(Color.Pink)
}
}