文档管理中心

如何解决子窗口设置状态栏颜色失败问题

问题现象

通过createSubWindow开启子窗口后,调用setWindowSystemBarProperties方法设置状态栏颜色无效,如何设置状态栏颜色?

效果预览

背景知识

  • @ohos.window (窗口):提供管理窗口的一些基础能力,包括对当前窗口的创建、销毁、各属性设置,以及对各窗口间的管理调度。
  • setWindowSystemBarProperties:可以设置主窗口三键导航栏、状态栏的属性。
  • AppStorage:是应用全局的UI状态存储,和应用的进程绑定,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。
  • getLastWindow:获取当前应用内最上层显示的子窗口,若无应用子窗口或子窗口未调用showWindow()进行显示,则返回应用主窗口。
  • createWindow:创建子窗口或者系统窗口。
  • getLastWindow和createWindow区别如下:
展开

API

功能定位

应用场景

权限与限制

createWindow

用于创建新的窗口实例,属于主动生成窗口的操作。需明确指定窗口类型(如应用主窗口、子窗口或系统窗口)及相关参数。

创建弹窗、分屏窗口、初始化应用主窗口时动态生成窗口。

部分窗口类型(如系统窗口)需要特定权限。

getLastWindow

用于获取当前窗口栈中位于顶部的窗口实例(即最近使用的窗口),属于被动获取已有窗口的操作。

设置屏幕常亮、修改状态栏颜色、调整窗口方向。

若无活动窗口或窗口状态异常(如已被销毁),可能抛出错误码 1300002(窗口状态异常)。

解决方案

设置状态栏颜色需要在主窗口中设置才能生效,可以在EntryAbility中先获取到主窗口,存储后在子窗口中获取并使用。

  1. 在EntryAbility.ets中获取window.getLastWindow,使用AppStorage存储windowClass。
    收起
    自动换行
    深色代码主题
    复制
    1. onWindowStageCreate(windowStage: window.WindowStage): void {
    2. windowStage.loadContent('pages/Index', (err) => {
    3. let windowClass: window.Window | undefined = undefined;
    4. window.getLastWindow(this.context, (err: BusinessError, data) => {
    5. if (err.code) {
    6. return;
    7. }
    8. windowClass = data;
    9. // 通过AppStorage存储windowClass
    10. AppStorage.setOrCreate("windowClass", windowClass);
    11. AppStorage.setOrCreate('windowStage', windowStage);
    12. });
    13. if (err.code) {
    14. return;
    15. }
    16. });
    17. }
  2. 在子窗口中使用AppStorage取出windowClass设置状态栏颜色。
    收起
    自动换行
    深色代码主题
    复制
    1. // 通过AppStorage获取windowClass
    2. let windowClass = AppStorage.get('windowClass') as window.Window;
    3. // 配置状态栏颜色参数
    4. let sysBarProps: window.SystemBarProperties = {
    5. // 支持十六进制RGB/ARGB格式(如'#FFC0CB''FFC0CB'),需注意颜色值包含透明度通道。
    6. statusBarColor: '#0A59F7',
    7. statusBarContentColor: '#ffffff',
    8. };
    9. // 通过windowClass设置状态栏颜色
    10. try {
    11. let promise = windowClass.setWindowSystemBarProperties(sysBarProps);
    12. promise.then(() => {
    13. console.info('Succeeded in setting the system bar properties.');
    14. }).catch((err: BusinessError) => {
    15. console.error(`Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`);
    16. });
    17. } catch (exception) {
    18. console.error(`Failed to set the system bar properties. Cause code: ${exception.code}, message: ${exception.message}`);
    19. }

完整示例参考如下:

  1. Index.ets。
    收起
    自动换行
    深色代码主题
    复制
    1. import { display, window } from '@kit.ArkUI';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. let windowStage_: window.WindowStage | undefined = undefined;
    4. let sub_windowClass: window.Window | undefined = undefined;
    5. @Entry
    6. @Component
    7. struct Index {
    8. build() {
    9. Column() {
    10. Button('打开子窗口')
    11. .onClick(() => {
    12. this.createSubWindow();
    13. })
    14. .margin({ top: 60 })
    15. }
    16. .alignItems(HorizontalAlign.Center)
    17. .justifyContent(FlexAlign.Center)
    18. .height('100%')
    19. .width('100%')
    20. }
    21. private createSubWindow() {
    22. let displayClass: display.Display = display.getDefaultDisplaySync();
    23. // 计算中心点坐标
    24. let centerX: number = displayClass.width / 2;
    25. let centerY: number = displayClass.height / 2;
    26. // 获取windowStage
    27. windowStage_ = AppStorage.get('windowStage');
    28. // 1.创建应用子窗口。
    29. if (windowStage_ == null) {
    30. console.error('Failed to create the subwindow. Cause: windowStage_ is null');
    31. } else {
    32. windowStage_.createSubWindow("mySubWindow", (err: BusinessError, data) => {
    33. let errCode: number = err.code;
    34. if (errCode) {
    35. console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
    36. return;
    37. }
    38. sub_windowClass = data;
    39. if (!sub_windowClass) {
    40. console.error('sub_windowClass is null');
    41. return;
    42. }
    43. console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
    44. // 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
    45. sub_windowClass.moveWindowTo(centerX-300, centerY-300, (err: BusinessError) => {
    46. let errCode: number = err.code;
    47. if (errCode) {
    48. console.error('Failed to move the window. Cause:' + JSON.stringify(err));
    49. return;
    50. }
    51. console.info('Succeeded in moving the window.');
    52. });
    53. sub_windowClass.resize(600, 600, (err: BusinessError) => {
    54. let errCode: number = err.code;
    55. if (errCode) {
    56. console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
    57. return;
    58. }
    59. console.info('Succeeded in changing the window size.');
    60. });
    61. // 3.为子窗口加载对应的目标页面。
    62. sub_windowClass.setUIContent("pages/SubPage", (err: BusinessError) => {
    63. let errCode: number = err.code;
    64. if (errCode) {
    65. console.error('Failed to load the content. Cause:' + JSON.stringify(err));
    66. return;
    67. }
    68. console.info('Succeeded in loading the content.');
    69. if (!sub_windowClass) {
    70. console.error('sub_windowClass is null');
    71. return;
    72. }
    73. // 3.显示子窗口。
    74. sub_windowClass.showWindow((err: BusinessError) => {
    75. let errCode: number = err.code;
    76. if (errCode) {
    77. console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
    78. return;
    79. }
    80. console.info('Succeeded in showing the window.');
    81. });
    82. });
    83. });
    84. }
    85. }
    86. }
  2. SubPage.ets。
    收起
    自动换行
    深色代码主题
    复制
    1. import { window } from '@kit.ArkUI';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. @Entry
    4. @Component
    5. struct SubPage {
    6. build() {
    7. Column() {
    8. Text('Change BarColor')
    9. .fontSize(18)
    10. .fontWeight(FontWeight.Bold)
    11. .onClick(() => {
    12. // 通过AppStorage获取windowClass
    13. let windowClass = AppStorage.get('windowClass') as window.Window;
    14. // 配置状态栏颜色参数
    15. let sysBarProps: window.SystemBarProperties = {
    16. // 支持十六进制RGB/ARGB格式(如'#FFC0CB''FFC0CB'),需注意颜色值包含透明度通道。
    17. statusBarColor: '#0A59F7',
    18. statusBarContentColor: '#ffffff',
    19. };
    20. // 通过windowClass设置状态栏颜色
    21. try {
    22. let promise = windowClass.setWindowSystemBarProperties(sysBarProps);
    23. promise.then(() => {
    24. console.info('Succeeded in setting the system bar properties.');
    25. }).catch((err: BusinessError) => {
    26. console.error(`Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`);
    27. });
    28. } catch (exception) {
    29. console.error(`Failed to set the system bar properties. Cause code: ${exception.code}, message: ${exception.message}`);
    30. }
    31. })
    32. }
    33. .justifyContent(FlexAlign.Center)
    34. .backgroundColor('#EFF1F4')
    35. .height('100%')
    36. .width('100%')
    37. }
    38. }

常见FAQ

Q:调用window实例的setWindowSystemBarProperties接口时,设置isStatusBarLightIcon和isNavigationBarLightIcon属性无效。

A:可以参考:调用window实例的setWindowSystemBarProperties接口设置窗口状态栏和导航栏的高亮属性时不生效

Q:setWindowSystemBarProperties配置修改后,如何恢复默认配置,让其跟随深色模式切换?

A:setWindowSystemBarProperties配置修改后,无法直接恢复默认,需要根据系统的当前颜色模式来动态设置状态栏的颜色。详细可参考官方文档:在深色模式切换下如何适配状态栏颜色?

Q:window.createWindow接口是否有改动?之前在应用商店上架的版本弹窗能正常弹出,现在弹窗没法正常弹出。

A:从API 18版本起,创建窗口类型为window.WindowType.TYPE_FLOAT需要申请ohos.permission.SYSTEM_FLOAT_WINDOW权限才能弹窗,需要注意的是,该权限属于受限权限,当前仅PC/2in1设备应用可申请此权限,具体可参考:悬浮窗权限说明,在其他设备或场景下,请使用“画中画”功能,使用方式请参考:画中画开发指导

在 FAQ 中进行搜索
请输入您想要搜索的关键词