一、setWindowLayoutFullScreen(true)
- 設(shè)置主窗口或子窗口的布局是否為沉浸式布局,使用Promise異步回調(diào)。
- 沉浸式布局生效時(shí),布局不避讓狀態(tài)欄與導(dǎo)航欄,組件可能產(chǎn)生與其重疊的情況。
- 非沉浸式布局生效時(shí),布局避讓狀態(tài)欄與導(dǎo)航欄,組件不會(huì)與其重疊。
-
窗口的布局是否為沉浸式布局(該沉浸式布局狀態(tài)欄、導(dǎo)航欄仍然顯示)。true表示沉浸式布局;false表示非沉浸式布局。
1、EntryAbility直接設(shè)置
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
GlobalContext.get().setContext(this.context);
windowStage.getMainWindow().then((windowObj: window.Window) => {
//設(shè)置沉浸式
windowObj.setWindowLayoutFullScreen(true).catch((error: BusinessError) => {
hilog.error(0x0001, 'testTag', `Failed to setWindowLayoutFullScreen. Code: ${error.code}`);
})
//獲取并保存狀態(tài)欄高度
let avoidArea = windowObj.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
GlobalContext.get().setObject('state_bar_height', avoidArea.topRect.height);
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
})
}
}
未做狀態(tài)欄高度處理頁面代碼
@Entry
@Component
struct ImmersivePage {
build() {
Column() {
Text('setWindowLayoutFullScreen(true) 沉浸式')
.fontSize(50)
.fontColor(Color.Red)
}
.height('100%')
.width('100%')
}
}
狀態(tài)欄高度處理頁面代碼
@Entry
@Component
struct ImmersivePage {
build() {
Column() {
//添加狀態(tài)高度,可以封裝好一個(gè)通用
Text()
.backgroundColor(Color.Orange)
.height(px2vp(GlobalContext.get().getT<number>('state_bar_height')))
.width('100%')
Text('setWindowLayoutFullScreen(true) 沉浸式')
.fontSize(50)
.fontColor(Color.Red)
}
.height('100%')
.width('100%')
}
}

2、在對(duì)應(yīng)頁面設(shè)置setWindowLayoutFullScreen(true)沉浸式
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
GlobalContext.get().setContext(this.context);
windowStage.getMainWindow().then((windowObj: window.Window) => {
//獲取并保存狀態(tài)欄高度
let avoidArea = windowObj.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
GlobalContext.get().setObject('state_bar_height', avoidArea.topRect.height);
//保存窗口全局使用
GlobalContext.get().window = windowStage.getMainWindowSync()
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
})
}
}
@Entry
@Component
struct ImmersivePage {
build() {
Column() {
Text('當(dāng)前頁面設(shè)置setWindowLayoutFullScreen(true) 沉浸式')
.fontSize(50)
.fontColor(Color.Red)
}
.height('100%')
.width('100%')
}
aboutToAppear(): void {
//設(shè)置沉浸式
GlobalContext.get().window?.setWindowLayoutFullScreen(true)
}
aboutToDisappear(): void {
//沉浸式恢復(fù)
GlobalContext.get().window?.setWindowLayoutFullScreen(false)
}
}

3、使用方式總結(jié)
- 直接設(shè)置setWindowLayoutFullScreen(true),會(huì)導(dǎo)致全部頁面內(nèi)容到狀態(tài)欄,需要手動(dòng)添加狀態(tài)欄高度,可以考慮封裝好一個(gè)。
- 在頁面顯示前(aboutToAppear)獲取窗口(windowStage.getMainWindowSync())設(shè)置setWindowLayoutFullScreen(true)實(shí)現(xiàn)沉浸式,頁面銷毀(aboutToDisappear)設(shè)置setWindowLayoutFullScreen(false)回歸正常。
但是這樣做有個(gè)不好影響就是上一個(gè)頁面會(huì)有向下動(dòng)的視覺,體驗(yàn)不是很好。
二、expandSafeArea()
- 控制組件擴(kuò)展其安全區(qū)域。
1、未設(shè)置expandSafeArea
@Entry
@Component
struct ImmersivePage {
build() {
Column() {
Text('未設(shè)置 expandSafeArea 沉浸式')
.fontSize(50)
.fontColor(Color.Red)
}
.backgroundColor(Color.Orange)
.height('100%')
.width('100%')
}
}

2、設(shè)置expandSafeArea背景色沉浸
對(duì)父容器設(shè)置才是背景色沉浸,如果對(duì)Text設(shè)置會(huì)連帶文字一起沉浸到狀態(tài)欄。
@Entry
@Component
struct ImmersivePage {
build() {
Column() {
Text('設(shè)置 expandSafeArea 沉浸式')
.fontSize(50)
.fontColor(Color.Red)
}
.expandSafeArea()//設(shè)置沉浸式
.backgroundColor(Color.Orange)
.height('100%')
.width('100%')
}
}

3、設(shè)置expandSafeArea圖片沉浸
@Entry
@Component
struct ImmersivePage {
build() {
Stack() {
Image($rawfile('img.png'))
.expandSafeArea()//設(shè)置沉浸式
Text('設(shè)置 expandSafeArea 沉浸式')
.fontSize(50)
.fontColor(Color.White)
}
.height('100%')
.width('100%')
}
}
| 未設(shè)置沉浸式 | 設(shè)置沉浸式 |
|---|---|
![]() |
![]() |
4、多層組件也能設(shè)置expandSafeArea沉浸,只要父組件沒有限制其到狀態(tài)欄
@Entry
@Component
struct ImmersivePage {
build() {
Stack({ alignContent: Alignment.TopStart }) {
this.LayoutBuilder()
Text('設(shè)置 expandSafeArea 沉浸式')
.fontSize(50)
.fontColor(Color.White)
}
.height('100%')
.width('100%')
}
@Builder
LayoutBuilder() {
Column() {
Image($rawfile('img.png'))
.expandSafeArea() //設(shè)置沉浸式
}
}
}

5、多個(gè)組件也能設(shè)置expandSafeArea沉浸
@Entry
@Component
struct ImmersivePage {
build() {
Stack({ alignContent: Alignment.TopStart }) {
this.LayoutBuilder()
Text('設(shè)置 expandSafeArea 沉浸式')
.fontSize(50)
.fontColor(Color.White)
.expandSafeArea() //設(shè)置沉浸式1
}
.height('100%')
.width('100%')
}
@Builder
LayoutBuilder() {
Column() {
Image($rawfile('img.png'))
.expandSafeArea() //設(shè)置沉浸式2
}
}
}

6、使用方式總結(jié)
- expandSafeArea設(shè)置沉浸式更靈活,可以根據(jù)情況對(duì)其中一個(gè)或多個(gè)組件設(shè)置沉浸式
- expandSafeArea設(shè)置沉浸式不會(huì)導(dǎo)致頁面上下抖動(dòng)
7、說明
設(shè)置expandSafeArea屬性進(jìn)行組件繪制擴(kuò)展時(shí),組件不能設(shè)置固定寬高尺寸(百分比除外)。
安全區(qū)域不會(huì)限制內(nèi)部組件的布局和大小,不會(huì)裁剪內(nèi)部組件。
當(dāng)父容器是滾動(dòng)容器時(shí),設(shè)置expandSafeArea屬性不生效。
設(shè)置expandSafeArea()時(shí),不傳參,走默認(rèn)值處理;設(shè)置expandSafeArea([],[])時(shí),相當(dāng)于入?yún)⑹强諗?shù)組,此時(shí)設(shè)置expandSafeArea屬性不生效。
組件設(shè)置expandSafeArea之后生效的條件為:
1.type為SafeAreaType.KEYBOARD時(shí)默認(rèn)生效,組件不避讓鍵盤。
2.設(shè)置其他type,組件的邊界與安全區(qū)域重合時(shí)組件能夠延伸到安全區(qū)域下。例如:設(shè)備頂部狀態(tài)欄高度100,那么組件在屏幕中的絕對(duì)位置需要為0 <= y <= 100。
組件延伸到安全區(qū)域下,在安全區(qū)域處的事件,如點(diǎn)擊事件等可能會(huì)被系統(tǒng)攔截,優(yōu)先給狀態(tài)欄等系統(tǒng)組件響應(yīng)。
滾動(dòng)類容器內(nèi)的組件不建議設(shè)置expandSafeArea屬性,如果設(shè)置,需要按照組件嵌套關(guān)系,將當(dāng)前節(jié)點(diǎn)到滾動(dòng)類祖先容器間所有直接節(jié)點(diǎn)設(shè)置expandSafeArea屬性,否則expandSafeArea屬性在滾動(dòng)后可能會(huì)失效
三、Navigation()+NavDestination()
Navigation組件是路由導(dǎo)航的根視圖容器,一般作為Page頁面的根容器使用,其內(nèi)部默認(rèn)包含了標(biāo)題欄、內(nèi)容區(qū)和工具欄,其中內(nèi)容區(qū)默認(rèn)首頁顯示導(dǎo)航內(nèi)容(Navigation的子組件)或非首頁顯示(NavDestination的子組件),首頁和非首頁通過路由進(jìn)行切換。
作為子頁面的根容器,用于顯示Navigation的內(nèi)容區(qū)。
該組件從API Version 11開始默認(rèn)支持安全區(qū)避讓特性(默認(rèn)值為:expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])),開發(fā)者可以重寫該屬性覆蓋默認(rèn)行為,API Version 11之前的版本需配合expandSafeArea屬性實(shí)現(xiàn)安全區(qū)避讓。
@Builder
export function ImmersivePageBuilder() {
ImmersivePage()
}
@Component
export struct ImmersivePage {
pathStack: NavPathStack = new NavPathStack()
build() {
NavDestination() {
Stack({ alignContent: Alignment.TopStart }) {
Text('設(shè)置 NavDestination 沉浸式')
.fontSize(50)
.fontColor(Color.White)
}
.height('100%')
.width('100%')
}
.hideTitleBar(true) //設(shè)置沉浸式
.backgroundColor(Color.Orange) //設(shè)置沉浸式
.backgroundImage($rawfile('img.png'))//圖片設(shè)置沉浸式,容易圖片拉伸
.backgroundImageSize({ width: '100%', height: '100%' })//圖片設(shè)置沉浸式,容易圖片拉伸
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack
})
}
}
| 背景色沉浸式 | 圖片沉浸式 |
|---|---|
![]() |
![]() |
使用方式總結(jié)
- 默認(rèn)還是使用expandSafeArea實(shí)現(xiàn)沉浸式。
- 推薦在這使用顏色沉浸式,用圖片容易造成拉伸,確定用圖片可以單獨(dú)對(duì)圖片使用expandSafeArea沉浸式。




