Openharmony鸿蒙开发中,如何隐藏状态栏实现沉浸式效果?

阅读 2.1k
avatarAI BotBETA

在OpenHarmony鸿蒙开发中,要隐藏状态栏以实现沉浸式效果,你可以通过修改应用的界面布局和配置来实现。以下是一种常见的方法:

  1. 修改布局文件:在你的应用的布局文件中,将需要显示的内容放置在<root>标签内。确保你的主要内容不会被状态栏遮挡。
  2. 设置全屏模式:在应用的配置文件中(通常是config.json),设置全屏模式。这可以通过添加或修改display字段来实现。例如:
{
  "display": {
    "status_bar": {
      "visible": false
    }
  }
}

这将使得状态栏在应用运行时不可见,从而实现沉浸式效果。

  1. 处理系统UI变化:在某些情况下,系统可能会自动显示状态栏,例如当用户与通知交互时。为了处理这些情况,你可能需要在应用中监听系统UI的变化,并相应地调整你的布局。
  2. 测试不同设备和版本:由于不同设备和OpenHarmony版本可能会有不同的行为,建议在不同环境下进行充分测试,以确保沉浸式效果的一致性。

请注意,具体的实现细节可能会因OpenHarmony的版本和设备的不同而有所差异。因此,建议查阅最新的OpenHarmony文档和开发者指南以获取更详细和准确的信息。

1 个回答

开发应用沉浸式效果主要要考虑如下几个设计要素:
UI元素避让处理:导航条底部区域可以响应点击事件,除此之外的可交互UI元素和应用关键信息不建议放到导航条区域。
沉浸式效果处理:将状态栏和导航条颜色与界面元素颜色相匹配,不出现明显的突兀感。
针对上面的设计要求,可以通过如下两种方式实现应用沉浸式效果:

窗口全屏布局方案:调整布局系统为全屏布局,界面元素延伸到状态栏和导航条区域实现沉浸式效果,然后通过接口查询状态栏和导航条区域进行可交互元素避让处理。
组件安全区方案:布局系统保持安全区内布局(安全区:界面上排除状态栏和导航条区域),然后通过接口延伸绘制内容(如背景色,背景图)到状态栏和导航条区域实现沉浸式效果。
该方案下,界面元素仅做绘制延伸,无法单独布局到状态栏和导航条区域,针对需要单独布局UI元素到状态栏和导航条区域的场景建议使用窗口全屏布局方案处理。

以窗口全屏布局方案为例:
窗口全屏布局方案主要涉及以下应用扩展布局,全屏显示和应用扩展布局,隐藏避让区两个应用场景。

应用扩展布局,全屏显示
可以通过调用窗口强制全屏布局接口(setWindowLayoutFullScreen())实现界面元素覆盖到状态栏和导航条,获取到状态栏和导航条高度后进行避让处理。

该布局方案相对灵活,开发者可以通过获取到状态栏和导航条的区域,从而进行避让处理。

调用setWindowLayoutFullScreen()接口设置窗口全屏。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

export default class EntryAbility extends UIAbility {
  // ...

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        return;
      }

      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      // 1. 设置窗口全屏
      let isLayoutFullScreen = true;
      windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
        .then(() => {
          console.info('Succeeded in setting the window layout to full-screen mode.');
        })
        .catch((err: BusinessError) => {
          console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
        });
    });
  }
}

使用getWindowAvoidArea()接口获取布局遮挡区域(例如状态栏、导航条)。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        return;
      }

      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      // 1. 设置窗口全屏
      // ...

      // 2. 获取布局避让遮挡的区域
      let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
      let avoidArea = windowClass.getWindowAvoidArea(type);
      let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度
      AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
    });
  }
}

在布局中对具体控件布局避让遮挡的区域。例如对底部Tab组件增加对应高度或设置margin边距,底部若是List组件可增加一个空节点。

let storage = LocalStorage.getShared();

@Entry(storage)
@Component
struct Index {
  bottomRectHeight: string = AppStorage.get<number>('bottomRectHeight') + 'px';

  build() {
    Row() {
      Column() {
        Row() {
          Text('ROW1').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW2').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW3').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW4').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW5').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW6').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)
      }
      .width('100%')
      .height('100%')
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.SpaceBetween)
      .backgroundColor('#008000')
    }
    .margin({ bottom: this.bottomRectHeight }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
  }
}

image.png

更多可参考最新官方文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进