目录

控制窗口外观 (ArkTS)

场景介绍

窗口外观用于描述窗口在屏幕上的显示形态和视觉效果,目前支持通过设置异形窗口、窗口阴影、窗口圆角以及窗口背景色实现窗口外观设置。

开发者可以根据界面设计和交互需求,对窗口外观进行定制。例如:

异形窗口

异形窗口为非常规形状的窗口,掩码用于描述异形窗口的形状。仅应用子窗和全局悬浮窗可设置为异形窗口。

可通过setWindowMask()或setWindowMaskWithAlpha()接口设置异形窗口的掩码,以定义窗口的可见区域。

设置掩码后,窗口将按照掩码形状显示,窗口阴影将被禁用,窗口的圆角半径变为0。

此处以设置子窗的异形窗口为例。此例主要实现以下效果:

  1. 点击“Create Sub Window”按钮可以创建子窗。

  2. 创建子窗后,点击“setWindowMask for Sub Window”按钮,可通过setWindowMaskWithAlpha()接口设置子窗掩码。子窗发生以下变化:

    • 子窗变为三角形。
    • 子窗的阴影和圆角消失。
    • 子窗矩形区域的左上部分变为透明不可交互,通过点击“Create Test Window”按钮,事件透传到该按钮,创建出绿色的测试窗口。
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  // ...
  private windowMaskSub: window.Window | undefined = undefined;

  // ...
  setWindowMask(window: window.Window) {
    let windowMask: Uint8Array = new Uint8Array(this.winWidth * this.winHeight);
    for (let i = 0; i < this.winHeight; i++) {
      for (let k = 0; k < this.winWidth; k++) {
        if ((i + k) < (this.winHeight + this.winWidth) / 2) {
          windowMask[i * this.winWidth + k] = 0;
        } else {
          windowMask[i * this.winWidth + k] = 255;
        }
      }
    }
    window.setWindowMaskWithAlpha(windowMask, this.winWidth, this.winHeight);
  }

  build() {
    Row() {
      Scroll(){
        Column() {
          // ...
          Row() {
            Button('setWindowMask for Sub Window')
              .width('90%')
              .type(ButtonType.Capsule)
              .margin({
                top: 10
              }).fontSize(18)
              .onClick(() => {
                if(this.windowMaskSub) {
                  this.setWindowMask(this.windowMaskSub);
                }
              })
          }
        }
        .width('100%')
      }
    }
    .height('100%')
  }

}

窗口阴影

窗口阴影是显示在窗口边缘的投影效果,可以增强窗口与背景之间的层次感,使窗口呈现悬浮于背景之上的视觉效果。

设置窗口圆角

窗口背景色

窗口背景色用于控制窗口内容区域或窗口容器区域的背景显示效果。

开发者可根据业务场景,选择设置应用内容区域背景色,或设置包含标题栏在内的窗口容器背景色,以实现页面背景透明、窗口整体配色统一等效果。

示例代码如下:

import { ColorMetrics, window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';

const DOMAIN = 0x0000;

@Entry
@Component
struct Index {
  @StorageLink('mainWindow') mainWindow: window.Window | undefined = undefined;

  @State alpha: number = 0;
  @State red: number = 0;
  @State green: number = 0;
  @State blue: number = 0;
  @State statusText: string = 'Move the sliders to change the current window background color.';
  @State applyModeText: string = 'Current mode: string (#AARRGGBB)';

  // 将0~255的通道值转换成两位十六进制字符串,用于拼接 #AARRGGBB。
  private toHex(value: number): string {
    return Math.round(value).toString(16).padStart(2, '0').toUpperCase();
  }

  // 按ARGB顺序生成当前窗口背景色的十六进制字符串。
  private getColorValue(): string {
    return `#${this.toHex(this.alpha)}${this.toHex(this.red)}${this.toHex(this.green)}${this.toHex(this.blue)}`;
  }
  // ...
  // 直接用ColorMetrics.rgba(...)设置窗口背景色。
  private applyByColorMetrics(): void {
    if (!this.mainWindow) {
      this.statusText = 'Current window is unavailable.';
      return;
    }

    try {
      const alpha = Math.round(this.alpha) / 255;
      const colorMetrics = ColorMetrics.rgba(Math.round(this.red), Math.round(this.green),
                            Math.round(this.blue), alpha);
      this.mainWindow.setWindowBackgroundColor(colorMetrics);
      this.applyModeText = 'Current mode: ColorMetrics.rgba(...)';
      this.statusText = `setWindowBackgroundColor(ColorMetrics.rgba(${Math.round(this.red)}, ${Math.round(this.green)}, ${Math.round(this.blue)}, ${alpha.toFixed(2)})) success`;
      hilog.info(DOMAIN, 'backgroundColor', this.statusText);
    } catch (err) {
      this.statusText = `setWindowBackgroundColor by ColorMetrics failed: ${JSON.stringify(err)}`;
      hilog.error(DOMAIN, 'backgroundColor', this.statusText);
    }
  }

  // ...
}