直接跳到内容

安全区适配

介绍

框架默认使用全局安全区进行页面内边距避让,避免内容被状态栏、刘海或导航条遮挡。安全区数据由 WindowAdapter 监听并写入全局状态,页面只需读取即可。

安全区监听与更新

安全区监听在 entry/src/main/ets/adapter/WindowAdapter.ets 中完成,应用启动时会初始化该适配器并监听系统避让区域变化,然后更新全局安全区状态。

核心流程:

  • 通过 window.getWindowAvoidArea() 读取系统与导航栏避让区域。
  • 将 px 转换为 vp 后写入 WindowSafeAreaState
  • 监听 avoidAreaChange 动态更新。

页面使用方式

AppNavDestination 默认启用安全区,会自动为页面加上内边距:

ts
import { AppNavDestination } from "ui";
import SafeAreaDemoViewModel from "../viewmodel/SafeAreaDemoViewModel";

/**
 * @file 安全区示例页视图
 */
@ComponentV2
export struct SafeAreaDemoPage {
  /**
   * 安全区示例页 ViewModel
   */
  @Local
  private vm: SafeAreaDemoViewModel = new SafeAreaDemoViewModel();

  /**
   * 构建安全区示例页
   * @returns {void} 无返回值
   */
  build(): void {
    AppNavDestination({
      title: $r("app.string.demo_safe_area_title"),
      viewModel: this.vm
    }) {
      Text("安全区示例");
    };
  }
}

对应的 ViewModel:

ts
import { BaseViewModel } from "base";

/**
 * @file 安全区示例页 ViewModel
 */
@ObservedV2
export default class SafeAreaDemoViewModel extends BaseViewModel {
}

如果需要读取具体安全区值,可直接拿全局状态:

ts
import { getWindowSafeAreaState, WindowSafeAreaState } from "state";

/**
 * @file 安全区数值读取示例
 */
@ComponentV2
export struct SafeAreaInsetSample {
  /**
   * 窗口安全区状态
   */
  @Local
  private windowSafeAreaState: WindowSafeAreaState = getWindowSafeAreaState();

  /**
   * 构建示例
   * @returns {void} 无返回值
   */
  build(): void {
    Text(this.windowSafeAreaState.topInset.toFixed(2));
  }
}

覆盖默认安全区

AppNavDestination 内置安全区,如果你的页面需要自定义内边距(例如首页、沉浸式模块),可以关闭或覆盖:

ts
import { AppNavDestination } from "ui";
import MainViewModel from "../viewmodel/MainViewModel";

/**
 * @file 主页面视图
 */
@ComponentV2
export struct MainPage {
  /**
   * 主页面 ViewModel
   */
  @Local
  private vm: MainViewModel = new MainViewModel();

  /**
   * 构建主页面
   * @returns {void} 无返回值
   */
  build(): void {
    AppNavDestination({
      title: $r("app.string.main_title"),
      viewModel: this.vm,
      safeAreaEnabled: false,
      paddingValue: { top: 0, left: 0, right: 0, bottom: 0 }
    }) {
      Text("自定义安全区页面");
    };
  }
}

API 说明

文件位置:core/state/src/main/ets/WindowSafeAreaState.ets

WindowSafeAreaState 属性

参数说明类型默认值
topInset顶部安全区高度(vp)number0
leftInset左侧安全区宽度(vp)number0
bottomInset底部安全区高度(vp)number0
rightInset右侧安全区宽度(vp)number0

WindowSafeAreaState 方法

方法说明参数返回值
updateSafeArea更新安全区数据topInset: number
leftInset: number
bottomInset: number
rightInset: number
void
updateSafeAreaByInsets使用结构体更新安全区insets: SafeAreaInsetsvoid

全局函数

方法说明参数返回值
getWindowSafeAreaState获取全局安全区状态-WindowSafeAreaState

注意事项

  • 安全区是全局状态,单位为 vp。
  • 默认情况下不需要手动处理安全区,AppNavDestination 已封装。
  • 只有在沉浸式或自定义布局时才覆盖安全区设置。