The immersive mode is a design mode that reduces interference from irrelevant elements to make the app UI more focused on content display, thereby improving user experience. A full-screen app window typically consists of the following UI elements: status bar, app UI, and bottom navigation bar. The status bar and navigation bar are called avoid areas in immersive mode, and the areas outside the avoid areas are called safe areas (as shown in the following figure). To develop an immersive page, you can extend the app page to the status bar and navigation bar to achieve the following purposes:

This topic describes the immersive development principles and implementation schemes, and provides solutions to adaptation problems in common immersive page development scenarios.
The implementation of the immersive window is based on the following factors:
The immersive effect of a page can be implemented at the window and component levels.
When a component overlaps the avoid area, set the background() attribute of the component to extend the component background to the avoid area while keeping the page layout in the safe area.
The background() API is a component-level API. Different background colors can be set for different components and extended to the corresponding avoid area. For example, the red background can be set for the top component and extended to the top status bar, and the blue background can be set for the bottom component and extended to the bottom navigation bar. If the background color of the page is unified, you can set the background() attribute of the outermost parent component to implement the immersive effect of the page.
In this solution, you only need to set the code attribute once to implement the immersive effect of the same component in different window modes and directions. However, the UI elements are only extended and cannot be independently arranged in the status bar and navigation bar. When the page supports scrolling, the scrolling area cannot be extended to the status bar and navigation bar.
Original Layout (Using backgroundColor()) | Immersive Component Background |
|---|---|
|
|
backgroundColor(): The background color is confined within the safe area.
background(): The background color extends to the top status bar and bottom navigation bar.
By setting ignoreLayoutSafeArea() and setting the height to LayoutPolicy.matchParent to adapt to the parent component, the page background and layout extend to the top status bar and bottom navigation bar. This is a component-level solution and needs to be configured for each page separately. When the page content conflicts with the safe area, you need to manually avoid the conflict.
Set the expandSafeArea attribute of the component to extend the safe area of the component to the status bar or navigation bar while keeping the child components in the safe area. You can specify the safe area type (SafeAreaType) and extension direction (SafeAreaEdge). For details about the solution, see Component Safe Area Scheme.
Original Layout | Extension to Status Bar and Navigation Bar | Extension to Status Bar Only | Extension to Navigation Bar Only |
|---|---|---|---|
|
|
|
|
Call the setWindowLayoutFullScreen() API to set the window to the immersive layout. The page layout is extended from the safe area to the entire window (including the status bar and navigation bar). The layout extension effect is the same as that of immersive component page.
This is a window-level solution. When the immersive layout takes effect, the full-screen mode is enabled for all pages. You need to avoid non-safe areas on each page.
The following table compares the solutions.
Item | Immersive Component Background | Immersive Component Page | Safe Area Extension | Immersive Window Display |
|---|---|---|---|---|
Level | Component | Component | Component | Window |
Description | Only the background extends to the avoid area. The content is in the safe area by default. | Both the background and content extend to the avoid area. | Only the background extends to the avoid area. The content is in the safe area by default. The system safe area type and extension direction can be specified. | The layouts of all pages extend to the full screen, and automatic avoidance is not performed. |
Usage scenario | Only the page background should be immersive. | The component content needs to completely cover the screen. | The extension area type needs to be specified for partial extension. | All pages of the app need to be immersive. |
Advantage | Easy to use and understand. One-time configuration can adapt to different window modes and directions. Extension of multiple components with different backgrounds is supported. | Easy to use and understand. One-time configuration can adapt to different window modes and directions. | Different safe areas can be extended. Child components are still deployed in the safe area, and no additional avoidance processing is required. | Globally effective, with centralized adaptation logic. |
Disadvantage | The scrolling content cannot extend to the avoid area. Separate configuration is required for each page. | The content is prone to conflict with the elements in the avoid area, and manual processing is required. Separate configuration is required for each page. | The scrolling content cannot extend to the avoid area. The parameters are complex and hard to understand. | You need to manually calculate the height of the avoid area and process all content avoidance. |
The immersive effect of a window is implemented by different pages, and the immersive effect of a page is implemented by the combination of immersive policies of different components. To implement the immersive effect of an app, you are advised to configure different immersive policies for each page through the component-level solution.
The avoid area may contain content (such as the battery level and time in the status bar) or gesture interaction (such as tapping or swiping up on the navigation bar). After the immersive effect of the app page is implemented, UI elements in the avoid area may be blocked, or visual or interaction conflicts may occur. In this case, you can select a proper method to adapt to different scenarios.
Displaying the Status Bar and Navigation Bar | Hiding the Status Bar and Navigation Bar |
|---|---|
|
|
Before Avoidance | After Avoidance |
|---|---|
|
|
In freeform window on PCs, tablets, and Mate XTs devices, you can set the title bar of an app window to be invisible to extend the app page to the title bar, implementing immersive display of the window. The component-level solution does not apply to the title bar of the freeform window. You need to customize the solution.
The title bar of a freeform window contains the app icon, app name, and three buttons (full screen/restore, minimize, and close). You can set the title bar to invisible to hide the app icon and app name, and retain the three buttons to implement the immersive window effect.

The page background needs to be extended to the status bar and navigation bar, and the page content is displayed in the safe area.
Full Screen | Split Screen | Floating Window | ||
|---|---|---|---|---|
|
|
| ||
Set background() for the component to extend the background. The content is automatically retained in the safe area and adapts to the avoid area changes in different window modes and directions.
Column() {
// ...
}
// Add a background for the component to achieve immersive background effect
.background('#F1F3F5') Column() {
// ...
}
// Expands the layout safe area of a component.
.ignoreLayoutSafeArea()
.height(LayoutPolicy.matchParent) // Get the avoid area. this.mainWindowInfo.avoidSystem = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
public onAvoidAreaChange: (avoidOptions: window.AvoidAreaOptions) => void =
(avoidOptions: window.AvoidAreaOptions) => {
if (avoidOptions.type === window.AvoidAreaType.TYPE_SYSTEM) {
// Default area of the system.
this.mainWindowInfo.avoidSystem = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_CUTOUT) {
// Cutout area.
this.mainWindowInfo.avoidCutout = avoidOptions.area;
this.updateAvoidPadding(avoidOptions.area);
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_SYSTEM_GESTURE) {
// Side return gesture area.
this.mainWindowInfo.avoidSystemGesture = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_KEYBOARD) {
// Fixed soft keyboard area.
this.mainWindowInfo.avoidKeyboard = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
// Bottom navigation bar.
this.mainWindowInfo.avoidNavigationIndicator = avoidOptions.area;
}
}; Column() {
// ...
}
// ...
// Set the top and bottom padding to avoid status bar and navigation bar.
.padding({
top: this.windowUtil?.mainWindowInfo.avoidSystem?.topRect.height + 'px',
bottom: this.windowUtil?.mainWindowInfo.avoidNavigationIndicator?.bottomRect.height + 'px'
}) You are advised to use the preceding two solutions, which are easier to understand and implement than the immersive window display and safe area extension solutions. In addition, the two solutions automatically adapt to different window modes and directions.
In scenarios where the visible area of the screen needs to be fully utilized, to display important information or operation buttons on the status bar, you need to not only hide the original status bar and navigation bar, but also avoid the cutout area. In this case, you can make the background fully immersive and avoid the cutout area in the content area.
In the following scenarios, the cutout area size may change. Therefore, you need to listen for the avoid area height and other changes to ensure that the UI layout is adjusted timely.
The following figures show the device rotation effect.
Portrait with Top Notch | Landscape with Left Notch | Portrait with Bottom Notch | Inverted Landscape with Right Notch |
|---|---|---|---|
|
|
|
|
Column() {
// ...
}
// Expands the layout safe area of a component.
.ignoreLayoutSafeArea()
.height(LayoutPolicy.matchParent) // Hide the status bar and navigation bar.
this.mainWindow.setWindowSystemBarEnable([]).catch((error: BusinessError) => {
let err = error as BusinessError;
hilog.error(0x0000, 'testLog', `setWindowSystemBarEnable failed. Code:${err.code}, message:${err.message}`);
}); public onAvoidAreaChange: (avoidOptions: window.AvoidAreaOptions) => void =
(avoidOptions: window.AvoidAreaOptions) => {
if (avoidOptions.type === window.AvoidAreaType.TYPE_SYSTEM) {
// Default area of the system.
this.mainWindowInfo.avoidSystem = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_CUTOUT) {
// Cutout area.
this.mainWindowInfo.avoidCutout = avoidOptions.area;
this.updateAvoidPadding(avoidOptions.area);
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_SYSTEM_GESTURE) {
// Side return gesture area.
this.mainWindowInfo.avoidSystemGesture = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_KEYBOARD) {
// Fixed soft keyboard area.
this.mainWindowInfo.avoidKeyboard = avoidOptions.area;
} else if (avoidOptions.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
// Bottom navigation bar.
this.mainWindowInfo.avoidNavigationIndicator = avoidOptions.area;
}
}; updateAvoidPadding(area: window.AvoidArea) {
const avoidAreaPadding: Padding = {};
try {
// Top cutout area: set top padding.
if (area.topRect.height > 0) {
avoidAreaPadding.top = this.uiContext?.px2vp(area.topRect.height + area.topRect.top);
}
// Left cutout area: set left padding.
if (area.leftRect.width > 0) {
avoidAreaPadding.left = this.uiContext?.px2vp(area.leftRect.left + area.leftRect.width);
}
// Right cutout area: set right padding.
if (area.rightRect.width > 0) {
avoidAreaPadding.right = this.uiContext?.px2vp(display.getDefaultDisplaySync().width - area.rightRect.left);
}
// Bottom cutout area: set bottom padding.
if (area.bottomRect.height > 0) {
avoidAreaPadding.bottom = this.uiContext?.px2vp(display.getDefaultDisplaySync().height - area.bottomRect.top);
}
} catch (error) {
let err = error as BusinessError;
hilog.error(0x0000, 'TestLog', `Failed to set avoid padding. Code: ${err.code}, message: ${err.message}`);
}
this.mainWindowInfo.avoidAreaPadding = avoidAreaPadding;
} Column() {
// ...
}
// ...
// Set paddings to avoid notch.
.padding(this.mainWindowInfo?.avoidAreaPadding) In a freeform window, you need to hide the default title bar and reserve the close, minimize, and maximize buttons so that the page can extend to the original title bar.

this.mainWindow.setWindowDecorVisible(false);
this.mainWindow.setWindowDecorHeight(56);
this.mainWindow.setDecorButtonStyle({ buttonIconSize: 24 }); public onWindowButtonRectChange: (titleButtonRect: window.TitleButtonRect) => void =
(titleButtonRect: window.TitleButtonRect) => {
// Update the rectangle information of the title bar button.
this.mainWindowInfo.titleButtonRect = titleButtonRect;
} Column() {
// ...
}
.padding({
right: this.mainWindowInfo.isImmersive === ImmersiveType.IMMERSIVE ? this.mainWindowInfo.titleButtonRect?.width :
0
})