HarmonyOS Developer 开发指导

丶龙八夷
发布于 2023-3-26 19:58
浏览
0收藏

通知概述

通知简介

应用可以通过通知接口发送通知消息,终端用户可以通过通知栏查看通知内容,也可以点击通知来打开应用。

通知常见的使用场景:

  • 显示接收到的短消息、即时消息等。
  • 显示应用的推送消息,如广告、版本更新等。
  • 显示当前正在进行的事件,如下载等。

HarmonyOS通过ANS(Advanced Notification Service,通知系统服务)对通知类型的消息进行管理,支持多种通知类型,如基础类型通知、进度条类型通知。

通知业务流程

通知业务流程由通知子系统、通知发送端、通知订阅端组成。

一条通知从通知发送端产生,通过​​IPC通信​​发送到通知子系统,再由通知子系统分发给通知订阅端。

系统应用还支持通知相关配置,如使能开关、配置参数由系统配置发起请求,发送到通知子系统存储到内存和数据库。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

发布基础类型通知

基础类型通知主要应用于发送短信息、提示信息、广告推送等,支持普通文本类型、长文本类型、多行文本类型和图片类型。

表1 基础类型通知中的内容分类

类型

描述

NOTIFICATION_CONTENT_BASIC_TEXT

普通文本类型。

NOTIFICATION_CONTENT_LONG_TEXT

长文本类型。

NOTIFICATION_CONTENT_MULTILINE

多行文本类型。

NOTIFICATION_CONTENT_PICTURE

图片类型。

目前系统仅通知栏订阅了通知,将通知显示在通知栏里。基础类型通知呈现效果示意图如下所示。

图1 基础类型通知呈现效果示意图

HarmonyOS Developer 开发指导-鸿蒙开发者社区

接口说明

通知发布接口如下表所示,不同发布类型通知由​​NotificationRequest​​的字段携带不同的信息。

接口名

描述

publish(request: NotificationRequest, callback: AsyncCallback<void>): void

发布通知。

cancel(id: number, label: string, callback: AsyncCallback<void>): void

取消指定的通知。

cancelAll(callback: AsyncCallback<void>): void;

取消所有该应用发布的通知。

开发步骤

  1. 导入模块。

import NotificationManager from '@ohos.notificationManager';
  1. 构造NotificationRequest对象,并发布通知。
  • 普通文本类型通知由标题、文本内容和附加信息三个字段组成,其中标题和文本内容是必填字段,大小均需要小于200字节。

let notificationRequest = {
  id: 1,
  content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
    normal: {
      title: 'test_title',
      text: 'test_text',
      additionalText: 'test_additionalText',
    }
  }
}

NotificationManager.publish(notificationRequest, (err) => {
    if (err) {
        console.error(`[ANS] failed to publish, error[${err}]`);
        return;
    }
    console.info(`[ANS] publish success`);
});

运行效果如下图所示。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

  • 长文本类型通知继承了普通文本类型的字段,同时新增了长文本内容、内容概要和通知展开时的标题,其中长文本内容不超过1024字节,其他字段小于200字节。通知默认显示与普通文本相同,展开后,标题显示为展开后标题内容,内容为长文本内容。

let notificationRequest = {
  id: 1,
  content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT, // 长文本类型通知
    longText: {
      title: 'test_title',
      text: 'test_text',
      additionalText: 'test_additionalText',
      longText: 'test_longText',
      briefText: 'test_briefText',
      expandedTitle: 'test_expandedTitle',
    }
  }
}

// 发布通知
NotificationManager.publish(notificationRequest, (err) => {
    if (err) {
        console.error(`[ANS] failed to publish, error[${err}]`);
        return;
    }
    console.info(`[ANS] publish success`);
});

运行效果如下图所示。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

  • 多行文本类型通知继承了普通文本类型的字段,同时新增了多行文本内容、内容概要和通知展开时的标题,其字段均小于200字节。通知默认显示与普通文本相同,展开后,标题显示为展开后标题内容,多行文本内容多行显示。

let notificationRequest = {
  id: 1,
  content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE, // 多行文本类型通知
    multiLine: {
      title: 'test_title',
      text: 'test_text',
      briefText: 'test_briefText',
      longTitle: 'test_longTitle',
      lines: ['line_01', 'line_02', 'line_03', 'line_04'],
    }
  }
}

// 发布通知
NotificationManager.publish(notificationRequest, (err) => {
  if (err) {
    console.error(`[ANS] failed to publish, error[${err}]`);
    return;
  }
  console.info(`[ANS] publish success`);
});

运行效果如下图所示。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

  • 图片类型通知继承了普通文本类型的字段,同时新增了图片内容、内容概要和通知展开时的标题,图片内容为PixelMap型对象,其大小不能超过2M。

let notificationPicture: PixelMap = undefined; // 需要获取图片PixelMap信息
let notificationRequest = {
    id: 1,
    content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_PICTURE,
    picture: {
      title: 'test_title',
      text: 'test_text',
      additionalText: 'test_additionalText',
      briefText: 'test_briefText',
      expandedTitle: 'test_expandedTitle',
      picture: notificationPicture
    }
    }
}

// 发布通知
NotificationManager.publish(notificationRequest, (err) => {
    if (err) {
    console.error(`[ANS] failed to publish, error[${err}]`);
    return;
    }
    console.info(`[ANS] publish success `);
});

运行效果如下图所示。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

发布进度条类型通知

进度条通知也是常见的通知类型,主要应用于文件下载、事务处理进度显示。HarmonyOS提供了进度条模板,发布通知应用设置好进度条模板的属性值,如模板名、模板数据,通过通知子系统发送到通知栏显示。

目前系统模板仅支持进度条模板,通知模板​​NotificationTemplate​​中的data参数为用户自定义数据,用于显示与模块相关的数据,效果示意如下图所示。

HarmonyOS Developer 开发指导-鸿蒙开发者社区

接口说明

​isSupportTemplate()​​是查询模板是否支持接口,目前仅支持进度条模板。

  

  

接口名

描述

isSupportTemplate(templateName: string, callback: AsyncCallback<boolean>): void

查询模板是否存在。

开发步骤

  1. 导入模块。

import NotificationManager from '@ohos.notificationManager';
  1. 查询系统是否支持进度条模板,查询结果为支持downloadTemplate模板类通知。

NotificationManager.isSupportTemplate('downloadTemplate').then((data) => {
  console.info(`[ANS] isSupportTemplate success`);
  let isSupportTpl: boolean = data; // isSupportTpl的值为true表示支持支持downloadTemplate模板类通知,false表示不支持
  // ...
}).catch((err) => {
  console.error(`[ANS] isSupportTemplate failed, error[${err}]`);
});

说明

查询系统支持进度条模板后,再进行后续的步骤操作。

  1. 构造进度条模板对象,并发布通知。

let notificationRequest = {
  id: 1,
  content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
    normal: {
      title: 'test_title',
      text: 'test_text',
      additionalText: 'test_additionalText'
    }
  },
  // 构造进度条模板,name字段当前需要固定配置为downloadTemplate
  template: {
    name: 'downloadTemplate',
    data: { title: 'File Title', fileName: 'music.mp4', progressValue: 45 }
  }
}

// 发布通知
NotificationManager.publish(notificationRequest, (err) => {
  if (err) {
    console.error(`[ANS] failed to publish, error[${err}]`);
    return;
  }
  console.info(`[ANS] publish success `);
});

为通知添加行为意图

WantAgent提供了封装行为意图的能力,这里所说的行为意图主要是指拉起指定的应用组件及发布公共事件等能力。HarmonyOS支持以通知的形式,将WantAgent从发布方传递至接收方,从而在接收方触发WantAgent中指定的意图。例如,在通知消息的发布者发布通知时,通常期望用户可以通过通知栏点击拉起目标应用组件。为了达成这一目标,开发者可以将WantAgent封装至通知消息中,当系统接收到WantAgent后,在用户点击通知栏时触发WantAgent的意图,从而拉起目标应用组件。

为通知添加行为意图的实现方式如下图所示:发布通知的应用向应用组件管理服务AMS(Ability Manager Service)申请WantAgent,然后随其他通知信息一起发送给桌面,当用户在桌面通知栏上点击通知时,触发WantAgent动作。

图1 携带行为意图的通知运行机制

HarmonyOS Developer 开发指导-鸿蒙开发者社区

接口说明

具体接口描述,详见​​WantAgent接口文档​​。

接口名

描述

getWantAgent(info: WantAgentInfo, callback: AsyncCallback<WantAgent>): void

创建WantAgent。

trigger(agent: WantAgent, triggerInfo: TriggerInfo, callback?: Callback<CompleteData>): void

触发WantAgent意图。

cancel(agent: WantAgent, callback: AsyncCallback<void>): void

取消WantAgent。

getWant(agent: WantAgent, callback: AsyncCallback<Want>): void

获取WantAgent的want。

equal(agent: WantAgent, otherAgent: WantAgent, callback: AsyncCallback<boolean>): void

判断两个WantAgent实例是否相等。

开发步骤

  1. 导入模块。

import NotificationManager from '@ohos.notificationManager';
import wantAgent from '@ohos.app.ability.wantAgent';
  1. 创建WantAgentInfo信息。

场景一:创建拉起Ability的WantAgent的WantAgentInfo信息。

let wantAgentObj = null; // 用于保存创建成功的wantAgent对象,后续使用其完成触发的动作。

// 通过WantAgentInfo的operationType设置动作类型。
let wantAgentInfo = {
    wants: [
        {
            deviceId: '',
            bundleName: 'com.example.test',
            abilityName: 'com.example.test.MainAbility',
            action: '',
            entities: [],
            uri: '',
            parameters: {}
        }
    ],
    operationType: wantAgent.OperationType.START_ABILITY,
    requestCode: 0,
    wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
}

场景二:创建发布公共事件的WantAgent的WantAgentInfo信息。

let wantAgentObj = null; // 用于保存创建成功的WantAgent对象,后续使用其完成触发的动作。

// wantAgentInfo
let wantAgentInfo = {
    wants: [
        {
            action: 'event_name', // 设置事件名。
            parameters: {},
        }
    ],
    operationType: wantAgent.OperationType.SEND_COMMON_EVENT,
    requestCode: 0,
    wantAgentFlags: [wantAgent.WantAgentFlags.CONSTANT_FLAG],
}
  1. 创建WantAgent。

// 创建WantAgent
wantAgent.getWantAgent(wantAgentInfo, (err, data) => {
    if (err) {
        console.error('[WantAgent]getWantAgent err=' + JSON.stringify(err));
    } else {
        console.info('[WantAgent]getWantAgent success');
        wantAgentObj = data;
    }
});
  1. 构造NotificationRequest对象。

// 构造NotificationRequest对象
let notificationRequest = {
    content: {
        contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
        normal: {
            title: 'Test_Title',
            text: 'Test_Text',
            additionalText: 'Test_AdditionalText',
        },
    },
    id: 1,
    label: 'TEST',
    wantAgent: wantAgentObj,
}
  1. 发布WantAgent通知。

// 通知发送
NotificationManager.publish(notificationRequest, (err) => {
    if (err) {
        console.error(`[ANS] failed to publish, error[${err}]`);
        return;
    }
    console.info(`[ANS] publish success `);
});
  1. 用户通过点击通知栏上的通知,触发WantAgent的动作。

// 触发WantAgent
let triggerInfo = {
    code: 0
}
wantAgent.trigger(wantAgentObj, triggerInfo, (completeData) => {
    console.info('[WantAgent]getWantAgent success, completeData: ',  + JSON.stringify(completeData));
});

窗口开发概述

窗口模块的定义

窗口模块用于在同一块物理屏幕上,提供多个应用界面显示、交互的机制。

  • 对应用开发者而言,窗口模块提供了界面显示和交互能力。
  • 对终端用户而言,窗口模块提供了控制应用界面的方式。
  • 对整个操作系统而言,窗口模块提供了不同应用界面的组织管理逻辑。

窗口模块的用途

在HarmonyOS中,窗口模块主要负责以下职责:

  • 提供应用和系统界面的窗口对象。应用开发者通过窗口加载UI界面,实现界面显示功能。
  • 组织不同窗口的显示关系,即维护不同窗口间的叠加层次和位置属性。应用和系统的窗口具有多种类型,不同类型的窗口具有不同的默认位置和叠加层次(Z轴高度)。同时,用户操作也可以在一定范围内对窗口的位置和叠加层次进行调整。
  • 提供窗口装饰。窗口装饰指窗口标题栏和窗口边框。窗口标题栏通常包括窗口最大化、最小化及关闭按钮等界面元素,具有默认的点击行为,方便用户进行操作;窗口边框则方便用户对窗口进行拖拽缩放等行为。窗口装饰是系统的默认行为,开发者可选择启用/禁用,无需关注UI代码层面的实现。
  • 提供窗口动效。在窗口显示、隐藏及窗口间切换时,窗口模块通常会添加动画效果,以使各个交互过程更加连贯流畅。在HarmonyOS中,应用窗口的动效为默认行为,不需要开发者进行设置或者修改。
  • 指导输入事件分发。即根据当前窗口的状态或焦点,进行事件的分发。触摸和鼠标事件根据窗口的位置和尺寸进行分发,而键盘事件会被分发至焦点窗口。应用开发者可以通过窗口模块提供的接口设置窗口是否可以触摸和是否可以获焦。

基本概念

窗口类型

HarmonyOS的窗口模块将窗口界面分为系统窗口、应用窗口两种基本类型。

  • 系统窗口:系统窗口指完成系统特定功能的窗口。如音量条、壁纸、通知栏、状态栏、导航栏等。
  • 应用窗口:应用窗口区别于系统窗口,指与应用显示相关的窗口。根据显示内容的不同,应用窗口又分为应用主窗口、应用子窗口两种类型。

      ○ 应用主窗口:应用主窗口用于显示应用界面,会在"任务管理界面"显示。

      ○ 应用子窗口:应用子窗口用于显示应用的弹窗、悬浮窗等辅助窗口,不会在"任务管理界面"显示。应用子窗口的生命周期跟随应用主窗口。

实现原理

当前窗口的实现和开发与应用开发模型相关联,不同模型下的接口功能略有区别。当前应用开发模型分为FA模型和Stage模型。

两个模型的整体架构和设计思想,详见​​应用模型解读​​。

针对窗口开发,推荐使用Stage模型进行相关开发。

约束与限制

  • 应用主窗口与子窗口存在大小限制,宽度范围:[320, 2560],高度范围:[240, 2560],单位为vp。

管理应用窗口(Stage模型)

基本概念

窗口沉浸式能力:指对状态栏、导航栏等系统窗口进行控制,减少状态栏导航栏等系统界面的突兀感,从而使用户获得最佳体验的能力。

沉浸式能力只在应用主窗口作为全屏窗口时生效。通常情况下,应用子窗口(弹窗等辅助窗口)无法使用沉浸式能力。

场景介绍

在Stage模型下,管理应用窗口的典型场景有:

  • 设置应用主窗口属性及目标页面
  • 设置应用子窗口属性及目标页面
  • 体验窗口沉浸式能力

以下分别介绍具体开发方式。

接口说明

上述场景涉及的常用接口如下表所示。更多API说明请参见​​API参考​​。

实例名

接口名

描述

WindowStage

getMainWindow(callback: AsyncCallback<Window>): void

获取WindowStage实例下的主窗口。

此接口仅可在Stage模型下使用。

WindowStage

loadContent(path: string, callback: AsyncCallback<void>): void

为当前WindowStage的主窗口加载具体页面。

此接口仅可在Stage模型下使用。

WindowStage

createSubWindow(name: string, callback: AsyncCallback<Window>): void

创建子窗口。

此接口仅可在Stage模型下使用。

window静态方法

createWindow(config: Configuration, callback: AsyncCallback<Window>): void

创建系统窗口。

-config:创建窗口时的参数。

Window

setUIContent(path: string, callback: AsyncCallback<void>): void

为当前窗口加载具体页面。

Window

setWindowBackgroundColor(color: string, callback: AsyncCallback<void>): void

设置窗口的背景色。

Window

setWindowBrightness(brightness: number, callback: AsyncCallback<void>): void

设置屏幕亮度值。

Window

setWindowTouchable(isTouchable: boolean, callback: AsyncCallback<void>): void

设置窗口是否为可触状态。

Window

moveWindowTo(x: number, y: number, callback: AsyncCallback<void>): void

移动当前窗口位置。

Window

resize(width: number, height: number, callback: AsyncCallback<void>): void

改变当前窗口大小。

Window

setWindowLayoutFullScreen(isLayoutFullScreen: boolean, callback: AsyncCallback<void>): void

设置窗口布局是否为全屏布局。

Window

setWindowSystemBarEnable(names: Array<'status'|'navigation'>): Promise<void>

设置导航栏、状态栏是否显示。

Window

setWindowSystemBarProperties(systemBarProperties: SystemBarProperties, callback: AsyncCallback<void>): void

设置窗口内导航栏、状态栏属性。

systemBarProperties:导航栏、状态栏的属性集合。

Window

showWindow(callback: AsyncCallback<void>): void

显示当前窗口。

Window

destroyWindow(callback: AsyncCallback<void>): void

销毁当前窗口。

设置应用主窗口

在Stage模型下,应用主窗口由UIAbility创建并维护生命周期。在UIAbility的onWindowStageCreate回调中,通过WindowStage获取应用主窗口,即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性,如最大窗口宽度maxWindowWidth等,详见​​module.json5配置文件​​。

开发步骤
  1. 获取应用主窗口。通过getMainWindow接口获取应用主窗口。
  2. 设置主窗口属性。可设置主窗口的背景色、亮度值、是否可触等多个属性,开发者可根据需要选择对应的接口。本示例以设置“是否可触”属性为例。
  3. 为主窗口加载对应的目标页面。通过loadContent接口加载主窗口的目标页面。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage) {
        // 1.获取应用主窗口。
        let windowClass = null;
        windowStage.getMainWindow((err, data) => {
            if (err.code) {
                console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
                return;
            }
            windowClass = data;
            console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));
            // 2.设置主窗口属性。以设置"是否可触"属性为例。
            let isTouchable = true;
            windowClass.setWindowTouchable(isTouchable, (err) => {
                if (err.code) {
                    console.error('Failed to set the window to be touchable. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in setting the window to be touchable.');
            })
        })
        // 3.为主窗口加载对应的目标页面。
        windowStage.loadContent("pages/page2", (err) => {
            if (err.code) {
                console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in loading the content.');
        });
    }
};

设置应用子窗口

开发者可以按需创建应用子窗口,如弹窗等,并对其进行属性设置等操作。

开发步骤
  1. 创建应用子窗口。
    通过createSubWindow接口创建应用子窗口。
  2. 设置子窗口属性。
    子窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置窗口背景色、亮度等属性。
  3. 加载显示子窗口的具体内容。
    通过setUIContent和showWindow接口加载显示子窗口的具体内容。
  4. 销毁子窗口。
    当不再需要某些子窗口时,可根据具体实现逻辑,使用destroyWindow接口销毁子窗口。

import UIAbility from '@ohos.app.ability.UIAbility';

let windowStage_ = null;
let sub_windowClass = null;
export default class EntryAbility extends UIAbility {
    showSubWindow() {
        // 1.创建应用子窗口。
        windowStage_.createSubWindow("mySubWindow", (err, data) => {
            if (err.code) {
                console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
                return;
            }
            sub_windowClass = data;
            console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
            // 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
            sub_windowClass.moveWindowTo(300, 300, (err) => {
                if (err.code) {
                    console.error('Failed to move the window. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in moving the window.');
            });
            sub_windowClass.resize(500, 500, (err) => {
                if (err.code) {
                    console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in changing the window size.');
            });
            // 3.为子窗口加载对应的目标页面。
            sub_windowClass.setUIContent("pages/page3", (err) => {
                if (err.code) {
                    console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in loading the content.');
                // 3.显示子窗口。
                sub_windowClass.showWindow((err) => {
                    if (err.code) {
                        console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
                        return;
                    }
                    console.info('Succeeded in showing the window.');
                });
            });
        })
    }

    destroySubWindow() {
        // 4.销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。
        sub_windowClass.destroyWindow((err) => {
            if (err.code) {
                console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in destroying the window.');
        });
    }

    onWindowStageCreate(windowStage) {
        windowStage_ = windowStage;
        // 开发者可以在适当的时机,如主窗口上按钮点击事件等,创建子窗口。并不一定需要在onWindowStageCreate调用,这里仅作展示
        this.showSubWindow();
    }

    onWindowStageDestroy() {
        // 开发者可以在适当的时机,如子窗口上点击关闭按钮等,销毁子窗口。并不一定需要在onWindowStageDestroy调用,这里仅作展示
        this.destroySubWindow();
    }
};

体验窗口沉浸式能力

在看视频、玩游戏等场景下,用户往往希望隐藏状态栏、导航栏等不必要的系统窗口,从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力(窗口沉浸式能力都是针对应用主窗口而言的),达到预期效果。

开发步骤
  1. 获取应用主窗口。
    通过getMainWindow接口获取应用主窗口。
  2. 实现沉浸式效果。有以下两种方式:
  • 方式一:调用setWindowSystemBarEnable接口,设置导航栏、状态栏不显示,从而达到沉浸式效果。
  • 方式二:调用setWindowLayoutFullScreen接口,设置应用主窗口为全屏布局;然后调用setWindowSystemBarProperties接口,设置导航栏、状态栏的透明度、背景/文字颜色以及高亮图标等属性,使之保持与主窗口显示协调一致,从而达到沉浸式效果。
  1. 加载显示沉浸式窗口的具体内容。
    通过loadContent接口加载沉浸式窗口的具体内容。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage) {
        // 1.获取应用主窗口。
        let windowClass = null;
        windowStage.getMainWindow((err, data) => {
            if (err.code) {
                console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
                return;
            }
            windowClass = data;
            console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));

            // 2.实现沉浸式效果。方式一:设置导航栏、状态栏不显示。
            let names = [];
            windowClass.setWindowSystemBarEnable(names, (err) => {
                if (err.code) {
                    console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in setting the system bar to be visible.');
            });
            // 2.实现沉浸式效果。方式二:设置窗口为全屏布局,配合设置导航栏、状态栏的透明度、背景/文字颜色及高亮图标等属性,与主窗口显示保持协调一致。
            let isLayoutFullScreen = true;
            windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => {
                if (err.code) {
                    console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in setting the window layout to full-screen mode.');
            });
            let sysBarProps = {
                statusBarColor: '#ff00ff',
                navigationBarColor: '#00ff00',
                // 以下两个属性从API Version 8开始支持
                statusBarContentColor: '#ffffff',
                navigationBarContentColor: '#ffffff'
            };
            windowClass.setWindowSystemBarProperties(sysBarProps, (err) => {
                if (err.code) {
                    console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in setting the system bar properties.');
            });
        })
        // 3.为沉浸式窗口加载对应的目标页面。
        windowStage.loadContent("pages/page2", (err) => {
            if (err.code) {
                console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in loading the content.');
        });
    }
};

管理应用窗口(FA模型)

基本概念

窗口沉浸式能力:指对状态栏、导航栏等系统窗口进行控制,减少状态栏导航栏等系统界面的突兀感,从而使用户获得最佳体验的能力。

沉浸式能力只在应用主窗口作为全屏窗口时生效。通常情况下,应用子窗口(弹窗等辅助窗口)无法使用沉浸式能力。

场景介绍

在FA模型下,管理应用窗口的典型场景有:

  • 设置应用子窗口属性及目标页面
  • 体验窗口沉浸式能力

以下分别介绍具体开发方式。

接口说明

上述场景涉及的常用接口如下表所示。更多API说明请参见​​API参考​​。

实例名

接口名

描述

window静态方法

createWindow(config: Configuration, callback: AsyncCallback<Window>): void

创建子窗口。

-config:创建窗口时的参数。

window静态方法

findWindow(name: string): Window

查找name所对应的窗口。

Window

SetUIContent(path: string, callback: AsyncCallback<void>): void

为当前窗口加载具体页面内容。

Window

moveWindowTo(x: number, y: number, callback: AsyncCallback<void>): void

移动当前窗口。

Window

setWindowBackgroundColor(color: string, callback: AsyncCallback<void>): void

设置窗口的背景色。

Window

setWindowBrightness(brightness: number, callback: AsyncCallback<void>): void

设置屏幕亮度值。

Window

resize(width: number, height: number, callback: AsyncCallback<void>): void

改变当前窗口大小。

Window

setWindowLayoutFullScreen(isLayoutFullScreen: boolean, callback: AsyncCallback<void>): void

设置窗口布局是否为全屏布局。

Window

setWindowSystemBarEnable(names: Array<'status'|'navigation'>): Promise<void>

设置导航栏、状态栏是否显示。

Window

setWindowSystemBarProperties(systemBarProperties: SystemBarProperties, callback: AsyncCallback<void>): void

设置窗口内导航栏、状态栏属性。

systemBarProperties:导航栏、状态栏的属性集合。

Window

showWindow(callback: AsyncCallback<void>): void

显示当前窗口。

Window

destroyWindow(callback: AsyncCallback<void>): void

销毁当前窗口。

设置应用子窗口

开发者可以按需创建应用子窗口,如弹窗等,并对其进行属性设置等操作。

开发步骤
  1. 创建/获取子窗口对象。
  • 可以通过window.createWindow接口创建子窗口。
  • 也可以通过window.findWindow接口来查找已经创建的窗口从而得到子窗口。

 import window from '@ohos.window';
   
   let windowClass = null;
   // 方式一:创建子窗口。
   let config = {name: "subWindow", windowType: window.WindowType.TYPE_APP, ctx: this.context};
   window.createWindow(config, (err, data) => {
       if (err.code) {
           console.error('Failed to create the subWindow. Cause: ' + JSON.stringify(err));
           return;
       }
       console.info('Succeeded in creating subWindow. Data: ' + JSON.stringify(data));
       windowClass = data;
   });
   // 方式二:查找得到子窗口。
   try {
       windowClass = window.findWindow('subWindow');
   } catch (exception) {
       console.error('Failed to find the Window. Cause: ' + JSON.stringify(exception));
   }
  1. 设置子窗口属性。

子窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置窗口背景色、亮度等属性。

// 移动子窗口位置。
windowClass.moveWindowTo(300, 300, (err) => {
  if (err.code) {
    console.error('Failed to move the window. Cause:' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in moving the window.');
});
// 改变子窗口大小。
windowClass.resize(500, 500, (err) => {
  if (err.code) {
    console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in changing the window size.');
});
  1. 加载显示子窗口的具体内容。

使用SetUIContent和showWindow接口加载显示子窗口的具体内容。

// 为子窗口加载对应的目标页面。
windowClass.SetUIContent("pages/page2", (err) => {
    if (err.code) {
        console.error('Failed to load the content. Cause: ' + JSON.stringify(err));
        return;
    }
    console.info('Succeeded in loading the content.');
    // 显示子窗口。
    windowClass.showWindow((err) => {
     if (err.code) {
            console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
            return;
        }
        console.info('Succeeded in showing the window.');
    });
});
  1. 销毁子窗口。

当不再需要某些子窗口时,可根据场景的具体实现逻辑,使用destroyWindow接口销毁子窗口。

// 销毁子窗口。当不再需要某些子窗口时,可根据场景的具体实现逻辑,使用destroy接口销毁子窗口。
windowClass.destroyWindow((err) => {
    if (err.code) {
        console.error('Failed to destroy the subwindow. Cause:' + JSON.stringify(err));
        return;
    }
    console.info('Succeeded in destroying the subwindow.');
});

体验窗口沉浸式能力

在看视频、玩游戏等场景下,用户往往希望隐藏状态栏、导航栏等不必要的系统窗口,从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力(窗口沉浸式能力都是针对应用主窗口而言的),达到预期效果。

开发步骤
  1. 获取主窗口对象。

说明

沉浸式能力需要在成功获取应用主窗口对象的前提下进行。

确保应用内最后显示的窗口为主窗口,然后再使用window.getLastWindow接口来获取得到主窗口。

import window from '@ohos.window';

let mainWindowClass = null;
// 获取主窗口。
window.getLastWindow(this.context,(err, data) => {
  if (err.code) {
    console.error('Failed to get the subWindow. Cause: ' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in getting subWindow. Data: ' + JSON.stringify(data));
  mainWindowClass = data;
});
  1. 实现沉浸式效果。有以下两种方式:​
  • 方式一:调用setWindowSystemBarEnable接口,设置导航栏、状态栏不显示,从而达到沉浸式效果。
  • 方式二:调用setWindowLayoutFullScreen接口,设置应用主窗口为全屏布局;然后调用setSystemProperties接口,设置导航栏、状态栏的透明度、背景/文字颜色以及高亮图标等属性,使之保持与主窗口显示协调一致,从而达到沉浸式效果。

// 实现沉浸式效果。方式一:设置导航栏、状态栏不显示。
let names = [];
mainWindowClass.setWindowSystemBarEnable(names, (err) => {
  if (err.code) {
    console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in setting the system bar to be visible.');
});
// 实现沉浸式效果。
// 方式二:设置窗口为全屏布局,配合设置状态栏、导航栏的透明度、背景/文字颜色及高亮图标等属性,与主窗口显示保持协调一致。
let isLayoutFullScreen = true;
mainWindowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => {
  if (err.code) {
    console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in setting the window layout to full-screen mode.');
});
let sysBarProps = {
  statusBarColor: '#ff00ff',
  navigationBarColor: '#00ff00',
  // 以下两个属性从API Version8开始支持。
  statusBarContentColor: '#ffffff',
  navigationBarContentColor: '#ffffff'
};
mainWindowClass.setWindowSystemBarProperties(sysBarProps, (err) => {
  if (err.code) {
    console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
    return;
  }
  console.info('Succeeded in setting the system bar properties.');
});
  1. 加载显示沉浸式窗口的具体内容。

使用SetUIContent和showWindow接口加载显示沉浸式窗口的具体内容。

// 为沉浸式窗口加载对应的目标页面。
mainWindowClass.SetUIContent("pages/page3", (err) => {
    if (err.code) {
        console.error('Failed to load the content. Cause: ' + JSON.stringify(err));
        return;
    }
    console.info('Succeeded in loading the content.');
    // 显示沉浸式窗口。
    mainWindowClass.showWindow((err) => {
        if (err.code) {
            console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
            return;
        }
        console.info('Succeeded in showing the window.');
    });
});




文章转载自:​​https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/application-window-fa-0000001427744668-V3?catalogVersion=V3​

标签
收藏
回复
举报
回复