HarmonyOS APP开发中的状态栏

举报
Jack20 发表于 2026/06/20 16:07:58 2026/06/20
【摘要】 HarmonyOS APP开发中的状态栏:@ohos.window状态栏控制、状态栏显隐、状态栏颜色/内容、沉浸式状态栏、状态栏与全屏模式📌 核心要点:通过 @ohos.window 模块精准控制状态栏的显隐、颜色与内容,实现沉浸式体验与全屏模式的无缝切换 一、背景与动机你有没有遇到过这样的场景?——精心设计了一个全屏的启动页,结果顶部状态栏硬生生把你的大图切掉一块;或者做视频播放器的时...

HarmonyOS APP开发中的状态栏:@ohos.window状态栏控制、状态栏显隐、状态栏颜色/内容、沉浸式状态栏、状态栏与全屏模式

📌 核心要点:通过 @ohos.window 模块精准控制状态栏的显隐、颜色与内容,实现沉浸式体验与全屏模式的无缝切换


一、背景与动机

你有没有遇到过这样的场景?——精心设计了一个全屏的启动页,结果顶部状态栏硬生生把你的大图切掉一块;或者做视频播放器的时候,状态栏的白色文字和你的浅色背景混在一起,用户根本看不清时间。

这就好比你精心布置了一个舞台,结果灯光师非要在舞台上方挂一排探照灯,你没法关掉它,也没法换个颜色。状态栏就是这样一个"既不能不要,又不太好用"的存在。

好在 HarmonyOS 给了我们足够的控制力。通过 @ohos.window 模块,我们可以像导演控制灯光一样,精确地操控状态栏的方方面面——显示还是隐藏、什么颜色、什么内容,甚至让它完全沉浸到我们的界面里。


二、核心原理

2.1 状态栏控制架构

状态栏的控制核心在于 Window 对象。每个 UIAbility 在创建时都会获得一个主窗口,我们通过这个窗口实例来操作状态栏属性。
图片.png

flowchart TD
    A[UIAbility启动] --> B[获取主窗口 WindowStage]
    B --> C[windowStage.getMainWindow]
    C --> D[主窗口实例 mainWindow]
    D --> E{状态栏控制}
    E --> F[setWindowLayoutFullScreen<br/>全屏布局]
    E --> G[setSpecificStatusBar<br/>状态栏显隐]
    E --> H[setWindowSystemBarProperties<br/>颜色/内容]
    E --> I[状态栏内容颜色<br/>isLightIcon]
    
    classDef primary fill:#4CAF50,stroke:#388E3C,color:#fff
    classDef warning fill:#FF9800,stroke:#F57C00,color:#fff
    classDef error fill:#F44336,stroke:#D32F2F,color:#fff
    classDef info fill:#2196F3,stroke:#1976D2,color:#fff
    classDef purple fill:#9C27B0,stroke:#7B1FA2,color:#fff
    
    class A,B primary
    class C,D info
    class E warning
    class F,G,H,I purple

2.2 关键API一览

API 功能 说明
setWindowLayoutFullScreen(isFullScreen) 设置窗口全屏布局 true时布局延伸到状态栏区域
setSpecificStatusBar(statusBar, status) 控制状态栏显隐 可单独控制状态栏或导航栏
setWindowSystemBarProperties(properties) 设置状态栏属性 颜色、内容颜色等
getWindowAvoidArea(type) 获取避让区域 获取状态栏高度等安全区域信息

2.3 沉浸式状态栏原理

沉浸式状态栏的本质是:让页面布局延伸到状态栏下方,同时保持状态栏可见。这就像给舞台加了一层透明玻璃——你能看到后面的布景,但灯光依然亮着。

关键步骤:

  1. 调用 setWindowLayoutFullScreen(true) 让布局延伸
  2. 获取状态栏避让区域高度
  3. 在页面顶部添加对应高度的 padding,防止内容被遮挡

三、代码实战

3.1 基础状态栏控制:显隐与颜色

最基础的场景——控制状态栏的显示/隐藏,以及修改状态栏背景色和内容颜色。

// StatusBarController.ets
// 状态栏基础控制器:显隐与颜色控制

import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct StatusBarBasicDemo {
  // 状态栏是否可见
  @State isStatusBarVisible: boolean = true;
  // 当前状态栏背景色
  @State currentBgColor: string = '#00000000';
  // 状态栏内容是否为浅色(白色图标/文字)
  @State isLightContent: boolean = false;

  // 预设颜色方案
  private colorSchemes: Array<{ name: string; bgColor: string; isLight: boolean }> = [
    { name: '透明沉浸', bgColor: '#00000000', isLight: true },
    { name: '深邃黑', bgColor: '#FF1A1A2E', isLight: true },
    { name: '海洋蓝', bgColor: '#FF0077B6', isLight: true },
    { name: '暖阳橙', bgColor: '#FFFF8800', isLight: false },
    { name: '薄荷绿', bgColor: '#FF2EC4B6', isLight: false },
  ];

  aboutToAppear(): void {
    this.initStatusBar();
  }

  // 初始化状态栏
  private async initStatusBar(): Promise<void> {
    try {
      const mainWindow = await this.getMainWindow();
      if (mainWindow) {
        // 默认设置为沉浸式
        await mainWindow.setWindowLayoutFullScreen(true);
      }
    } catch (error) {
      console.error(`初始化状态栏失败: ${JSON.stringify(error)}`);
    }
  }

  // 获取主窗口实例
  private async getMainWindow(): Promise<window.Window | null> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      return await window.getLastWindow(context);
    } catch (error) {
      console.error(`获取主窗口失败: ${JSON.stringify(error)}`);
      return null;
    }
  }

  // 切换状态栏显隐
  private async toggleStatusBar(visible: boolean): Promise<void> {
    try {
      const mainWindow = await this.getMainWindow();
      if (mainWindow) {
        await mainWindow.setSpecificStatusBar(window.StatusBarType.STATUS_BAR, visible);
        this.isStatusBarVisible = visible;
      }
    } catch (error) {
      console.error(`切换状态栏显隐失败: ${JSON.stringify(error)}`);
    }
  }

  // 应用颜色方案
  private async applyColorScheme(scheme: { bgColor: string; isLight: boolean }): Promise<void> {
    try {
      const mainWindow = await this.getMainWindow();
      if (mainWindow) {
        await mainWindow.setWindowSystemBarProperties({
          statusBarColor: scheme.bgColor,
          statusBarContentColor: scheme.isLight ? '#FFFFFF' : '#000000',
        });
        this.currentBgColor = scheme.bgColor;
        this.isLightContent = scheme.isLight;
      }
    } catch (error) {
      console.error(`应用颜色方案失败: ${JSON.stringify(error)}`);
    }
  }

  build() {
    Column() {
      // 顶部标题区域(带状态栏避让)
      Column() {
        Text('状态栏控制台')
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
        Text('掌控每一像素的视觉体验')
          .fontSize(14)
          .fontColor('#FFFFFFAA')
          .margin({ top: 4 })
      }
      .width('100%')
      .padding({ top: 56, left: 20, right: 20, bottom: 20 })
      .linearGradient({
        direction: GradientDirection.BottomRight,
        colors: [['#1A1A2E', 0], ['#16213E', 1]]
      })

      // 显隐控制
      Row() {
        Text('状态栏显隐')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
          .fontColor('#E0E0E0')
        Blank()
        Toggle({ type: ToggleType.Switch, isOn: this.isStatusBarVisible })
          .onChange((isOn: boolean) => {
            this.toggleStatusBar(isOn);
          })
          .selectedColor('#4CAF50')
      }
      .width('100%')
      .padding({ left: 20, right: 20, top: 16, bottom: 8 })

      // 颜色方案选择
      Text('颜色方案')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .fontColor('#E0E0E0')
        .margin({ left: 20, top: 16, bottom: 8 })

      Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
        ForEach(this.colorSchemes, (scheme: { name: string; bgColor: string; isLight: boolean }) => {
          Column() {
            Row()
              .width(40)
              .height(40)
              .borderRadius(20)
              .backgroundColor(scheme.bgColor === '#00000000' ? '#333333' : scheme.bgColor)
              .border({ width: 1, color: '#FFFFFF33' })
            Text(scheme.name)
              .fontSize(12)
              .fontColor('#BDBDBD')
              .margin({ top: 4 })
          }
          .margin({ left: 12, bottom: 12 })
          .onClick(() => {
            this.applyColorScheme(scheme);
          })
        })
      }
      .width('100%')
      .padding({ left: 8, right: 8 })

      // 当前状态信息
      Column() {
        Text('当前状态')
          .fontSize(14)
          .fontColor('#9E9E9E')
          .margin({ bottom: 8 })
        Row() {
          Text(`可见: ${this.isStatusBarVisible ? '✓' : '✗'}`)
            .fontSize(13)
            .fontColor('#BDBDBD')
          Text(`背景: ${this.currentBgColor}`)
            .fontSize(13)
            .fontColor('#BDBDBD')
            .margin({ left: 16 })
          Text(`内容: ${this.isLightContent ? '浅色' : '深色'}`)
            .fontSize(13)
            .fontColor('#BDBDBD')
            .margin({ left: 16 })
        }
      }
      .width('100%')
      .padding(16)
      .margin({ left: 20, right: 20, top: 16 })
      .borderRadius(12)
      .backgroundColor('#1E1E2E')
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#121212')
  }
}

3.2 沉浸式状态栏:避让区域计算与适配

沉浸式状态栏的关键在于正确处理避让区域——让内容延伸到状态栏下方,同时保证重要内容不被遮挡。

// ImmersiveStatusBar.ets
// 沉浸式状态栏:避让区域计算与适配

import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct ImmersiveStatusBarDemo {
  // 状态栏高度(避让区域)
  @State statusBarHeight: number = 0;
  // 是否使用沉浸式
  @State isImmersive: boolean = true;
  // 页面滚动偏移
  @State scrollOffset: number = 0;

  aboutToAppear(): void {
    this.setupImmersiveMode();
  }

  // 设置沉浸式模式并获取避让区域
  private async setupImmersiveMode(): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const mainWindow = await window.getLastWindow(context);

      // 开启全屏布局
      await mainWindow.setWindowLayoutFullScreen(true);

      // 设置状态栏为透明
      await mainWindow.setWindowSystemBarProperties({
        statusBarColor: '#00000000',
        statusBarContentColor: '#FFFFFF',
      });

      // 获取状态栏避让区域
      const avoidArea = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_STATUS_BAR);
      this.statusBarHeight = px2vp(avoidArea.topRect.height);

      console.info(`状态栏高度: ${this.statusBarHeight}vp`);
    } catch (error) {
      console.error(`设置沉浸式模式失败: ${JSON.stringify(error)}`);
    }
  }

  // 退出沉浸式模式
  private async exitImmersiveMode(): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const mainWindow = await window.getLastWindow(context);

      await mainWindow.setWindowLayoutFullScreen(false);
      await mainWindow.setWindowSystemBarProperties({
        statusBarColor: '#1A1A2E',
        statusBarContentColor: '#FFFFFF',
      });
    } catch (error) {
      console.error(`退出沉浸式模式失败: ${JSON.stringify(error)}`);
    }
  }

  build() {
    Stack() {
      // 背景大图(延伸到状态栏下方)
      Image($r('app.media.startIcon'))
        .width('100%')
        .height('100%')
        .objectFit(ImageFit.Cover)
        .blur(this.scrollOffset > 50 ? 10 : 0)

      // 内容层
      Scroll() {
        Column() {
          // 顶部安全区域占位
          Column()
            .width('100%')
            .height(this.isImmersive ? this.statusBarHeight : 0)

          // 顶部标题栏
          Row() {
            Text('🏠')
              .fontSize(20)
            Text('沉浸式体验')
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .fontColor('#FFFFFF')
              .margin({ left: 8 })
            Blank()
            Text('⚙️')
              .fontSize(20)
              .onClick(() => {
                this.isImmersive = !this.isImmersive;
                if (this.isImmersive) {
                  this.setupImmersiveMode();
                } else {
                  this.exitImmersiveMode();
                }
              })
          }
          .width('100%')
          .padding({ left: 20, right: 20, top: 8, bottom: 8 })

          // 内容卡片列表
          ForEach([
            { title: '什么是沉浸式状态栏', desc: '让页面布局延伸到状态栏区域,状态栏变为透明,内容与系统UI融为一体' },
            { title: '避让区域的作用', desc: '避让区域告诉我们状态栏占据了多少空间,以便在布局中添加对应的padding' },
            { title: 'px2vp的必要性', desc: '系统返回的避让区域高度是px单位,需要通过px2vp转换为vp才能在布局中使用' },
            { title: '全屏布局 vs 全屏模式', desc: '全屏布局(setWindowLayoutFullScreen)只影响布局延伸,全屏模式还会隐藏状态栏' },
          ], (item: { title: string; desc: string }, index: number) => {
            Column() {
              Text(item.title)
                .fontSize(16)
                .fontWeight(FontWeight.Medium)
                .fontColor('#FFFFFF')
              Text(item.desc)
                .fontSize(13)
                .fontColor('#FFFFFFAA')
                .margin({ top: 6 })
                .maxLines(2)
            }
            .width('100%')
            .padding(16)
            .margin({ top: index === 0 ? 16 : 8, left: 16, right: 16 })
            .borderRadius(12)
            .backgroundColor('#1E1E2ECC')
            .backdropBlur(20)
          })

          // 底部间距
          Column()
            .height(60)
        }
      }
      .width('100%')
      .height('100%')
      .scrollable(ScrollDirection.Vertical)
      .onScroll(() => {
        // 滚动时可以做一些视差效果
      })
    }
    .width('100%')
    .height('100%')
  }
}

3.3 视频播放器全屏模式:状态栏自动显隐

视频播放器是状态栏控制最典型的应用场景——播放时隐藏状态栏实现全屏,暂停或退出时恢复显示。

// VideoPlayerStatusBar.ets
// 视频播放器全屏模式:状态栏自动显隐

import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct VideoPlayerStatusBarDemo {
  // 是否全屏播放
  @State isFullScreen: boolean = false;
  // 控制栏是否可见
  @State isControlBarVisible: boolean = true;
  // 播放进度
  @State playProgress: number = 35;
  // 是否正在播放
  @State isPlaying: boolean = false;
  // 状态栏高度
  @State statusBarHeight: number = 0;
  // 控制栏自动隐藏定时器
  private hideTimer: number = -1;

  aboutToAppear(): void {
    this.getStatusBarHeight();
  }

  // 获取状态栏高度
  private async getStatusBarHeight(): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const mainWindow = await window.getLastWindow(context);
      const avoidArea = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_STATUS_BAR);
      this.statusBarHeight = px2vp(avoidArea.topRect.height);
    } catch (error) {
      console.error(`获取状态栏高度失败: ${JSON.stringify(error)}`);
    }
  }

  // 进入全屏模式
  private async enterFullScreen(): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const mainWindow = await window.getLastWindow(context);

      // 隐藏状态栏
      await mainWindow.setSpecificStatusBar(window.StatusBarType.STATUS_BAR, false);
      // 全屏布局
      await mainWindow.setWindowLayoutFullScreen(true);
      // 设置屏幕常亮(可选)
      await mainWindow.setWindowKeepScreenOn(true);

      this.isFullScreen = true;
      this.scheduleHideControlBar();
    } catch (error) {
      console.error(`进入全屏模式失败: ${JSON.stringify(error)}`);
    }
  }

  // 退出全屏模式
  private async exitFullScreen(): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const mainWindow = await window.getLastWindow(context);

      // 显示状态栏
      await mainWindow.setSpecificStatusBar(window.StatusBarType.STATUS_BAR, true);
      // 退出全屏布局
      await mainWindow.setWindowLayoutFullScreen(false);
      // 取消屏幕常亮
      await mainWindow.setWindowKeepScreenOn(false);

      this.isFullScreen = false;
      this.isControlBarVisible = true;
      clearTimeout(this.hideTimer);
    } catch (error) {
      console.error(`退出全屏模式失败: ${JSON.stringify(error)}`);
    }
  }

  // 定时隐藏控制栏
  private scheduleHideControlBar(): void {
    clearTimeout(this.hideTimer);
    this.hideTimer = setTimeout(() => {
      if (this.isPlaying) {
        this.isControlBarVisible = false;
      }
    }, 5000);
  }

  build() {
    Stack() {
      // 视频画面区域(模拟)
      Column() {
        Image($r('app.media.startIcon'))
          .width('100%')
          .height('100%')
          .objectFit(ImageFit.Cover)
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#000000')

      // 控制栏层
      if (this.isControlBarVisible || !this.isPlaying) {
        Column() {
          // 顶部控制栏
          Row() {
            Text('◀')
              .fontSize(22)
              .fontColor('#FFFFFF')
              .onClick(() => {
                if (this.isFullScreen) {
                  this.exitFullScreen();
                }
              })
            Text('视频标题 - 沉浸式播放体验')
              .fontSize(16)
              .fontColor('#FFFFFF')
              .margin({ left: 12 })
              .maxLines(1)
              .textOverflow({ overflow: TextOverflow.Ellipsis })
            Blank()
            Text(this.isFullScreen ? '⤓' : '⤒')
              .fontSize(22)
              .fontColor('#FFFFFF')
              .onClick(() => {
                if (this.isFullScreen) {
                  this.exitFullScreen();
                } else {
                  this.enterFullScreen();
                }
              })
          }
          .width('100%')
          .padding({ left: 16, right: 16, top: this.isFullScreen ? this.statusBarHeight + 8 : 8, bottom: 8 })
          .linearGradient({
            direction: GradientDirection.Bottom,
            colors: [['#000000CC', 0], ['#00000000', 1]]
          })

          Blank()

          // 底部控制栏
          Column() {
            // 进度条
            Row() {
              Text('02:15')
                .fontSize(12)
                .fontColor('#FFFFFFCC')
              Progress({ value: this.playProgress, total: 100, type: ProgressType.Linear })
                .width('60%')
                .color('#4CAF50')
                .backgroundColor('#FFFFFF33')
              Text('06:30')
                .fontSize(12)
                .fontColor('#FFFFFFCC')
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({ left: 16, right: 16 })

            // 播放控制按钮
            Row() {
              Text('⏮')
                .fontSize(24)
                .fontColor('#FFFFFF')
              Text(this.isPlaying ? '⏸' : '▶')
                .fontSize(32)
                .fontColor('#FFFFFF')
                .margin({ left: 24, right: 24 })
                .onClick(() => {
                  this.isPlaying = !this.isPlaying;
                  if (this.isPlaying && this.isFullScreen) {
                    this.scheduleHideControlBar();
                  }
                })
              Text('⏭')
                .fontSize(24)
                .fontColor('#FFFFFF')
              Blank()
              Text(this.isFullScreen ? '退出全屏' : '全屏')
                .fontSize(14)
                .fontColor('#FFFFFF')
                .padding({ left: 12, right: 12, top: 6, bottom: 6 })
                .borderRadius(16)
                .backgroundColor('#FFFFFF22')
                .onClick(() => {
                  if (this.isFullScreen) {
                    this.exitFullScreen();
                  } else {
                    this.enterFullScreen();
                  }
                })
            }
            .width('100%')
            .padding({ left: 16, right: 16, top: 8, bottom: this.isFullScreen ? 24 : 8 })
          }
          .linearGradient({
            direction: GradientDirection.Top,
            colors: [['#000000CC', 0], ['#00000000', 1]]
          })
        }
        .width('100%')
        .height('100%')
      }
      .animation({ duration: 300, curve: Curve.EaseInOut })

      // 点击区域:切换控制栏显隐
      Column()
        .width('60%')
        .height('60%')
        .onClick(() => {
          this.isControlBarVisible = !this.isControlBarVisible;
          if (this.isControlBarVisible && this.isPlaying && this.isFullScreen) {
            this.scheduleHideControlBar();
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}

四、踩坑与注意事项

4.1 避让区域高度的单位陷阱

这是最常见的一个坑——getWindowAvoidArea 返回的高度是 px 单位,而 ArkUI 布局使用的是 vp 单位。如果你直接用 px 值做 padding,在不同密度的设备上会出现明显的偏差。

// ❌ 错误:直接使用px值
const avoidArea = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_STATUS_BAR);
this.statusBarHeight = avoidArea.topRect.height; // px单位,直接用会偏大或偏小

// ✅ 正确:转换为vp
const avoidArea = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_STATUS_BAR);
this.statusBarHeight = px2vp(avoidArea.topRect.height); // 转换为vp

4.2 setWindowLayoutFullScreen 的时机问题

setWindowLayoutFullScreen 必须在窗口创建完成后调用。如果在 onCreate 阶段过早调用,可能会因为窗口尚未初始化而失败。推荐在 onWindowStageCreate 回调中或页面 aboutToAppear 中调用。

4.3 状态栏颜色不生效的问题

有时候你明明调用了 setWindowSystemBarProperties,但状态栏颜色就是不变。这通常是因为:

  1. 没有先设置全屏布局——在某些设备上,非全屏布局模式下状态栏颜色可能被系统覆盖
  2. 颜色格式不对——必须使用 #AARRGGBB 格式,缺了 alpha 通道会不生效
  3. 调用时机太早——窗口还没准备好就调用了

4.4 多窗口场景的注意事项

如果你的应用有多个窗口(比如画中画、悬浮窗),每个窗口需要独立控制自己的状态栏。获取窗口实例时要确保拿到的是正确的窗口。


五、HarmonyOS 6适配

5.1 API变更

变更项 HarmonyOS 5 HarmonyOS 6
状态栏控制 setSpecificStatusBar 新增 setStatusBarStyle 统一接口
避让区域 getWindowAvoidArea 新增 getWindowSafeArea 支持折叠屏
全屏模式 setWindowLayoutFullScreen 新增 setImmersiveMode 一键沉浸式

5.2 迁移指南

// HarmonyOS 5 写法
await mainWindow.setWindowLayoutFullScreen(true);
await mainWindow.setWindowSystemBarProperties({
  statusBarColor: '#00000000',
  statusBarContentColor: '#FFFFFF',
});

// HarmonyOS 6 写法(推荐)
await mainWindow.setImmersiveMode({
  enable: true,
  statusBarStyle: window.StatusBarStyle.TRANSPARENT,
  contentColor: '#FFFFFF',
});

5.3 折叠屏适配

HarmonyOS 6 加强了折叠屏设备的状态栏适配。折叠屏展开时状态栏可能位于不同位置,需要使用新的 getWindowSafeArea API 获取更精确的安全区域信息。


六、总结

mindmap
  root((状态栏控制))
    显隐控制
      setSpecificStatusBar
      全屏模式自动隐藏
      视频播放器场景
    颜色控制
      setWindowSystemBarProperties
      背景色 statusBarColor
      内容色 statusBarContentColor
      #AARRGGBB格式
    沉浸式
      setWindowLayoutFullScreen
      避让区域 getWindowAvoidArea
      px2vp单位转换
      顶部padding适配
    全屏模式
      隐藏状态栏+全屏布局
      屏幕常亮 setWindowKeepScreenOn
      控制栏自动隐藏
    踩坑要点
      px vs vp单位
      调用时机
      颜色格式
      多窗口独立控制
    HarmonyOS 6
      setImmersiveMode统一接口
      折叠屏安全区域
      getWindowSafeArea
    
    classDef primary fill:#4CAF50,stroke:#388E3C,color:#fff
    classDef warning fill:#FF9800,stroke:#F57C00,color:#fff
    classDef error fill:#F44336,stroke:#D32F2F,color:#fff
    classDef info fill:#2196F3,stroke:#1976D2,color:#fff
    classDef purple fill:#9C27B0,stroke:#7B1FA2,color:#fff
知识点 关键API 核心要点
状态栏显隐 setSpecificStatusBar 可独立控制状态栏和导航栏
状态栏颜色 setWindowSystemBarProperties 必须使用 #AARRGGBB 格式
沉浸式布局 setWindowLayoutFullScreen 布局延伸到状态栏下方
避让区域 getWindowAvoidArea + px2vp px 转 vp 是必须步骤
全屏模式 显隐 + 全屏布局 + 常亮 视频播放器典型场景

状态栏控制看似简单,实则暗藏玄机。从最基本的显隐切换到沉浸式适配,再到全屏模式的自动管理,每一步都需要对系统API有深入的理解。记住那个最关键的坑——px和vp的转换,这能帮你省去大半的调试时间。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。