• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 管理系统窗口(仅Stage模型支持)
2
3## 管理系统窗口概述
4
5在`Stage`模型下, 允许系统应用创建和管理系统窗口,包括音量条、壁纸、通知栏、状态栏、导航栏等。具体支持的系统窗口类型见[API参考-WindowType](../reference/apis/js-apis-window.md#windowtype7)。
6
7在窗口显示、隐藏及窗口间切换时,窗口模块通常会添加动画效果,以使各个交互过程更加连贯流畅。
8
9在OpenHarmony中,应用窗口的动效为默认行为,不需要开发者进行设置或者修改。
10
11相对于应用窗口,在显示系统窗口过程中,开发者可以自定义窗口的显示动画、隐藏动画。
12
13> **说明:**
14>
15> 本文档涉及系统接口的使用,请使用full-SDK进行开发。具体使用可见[full-SDK替换指南](../quick-start/full-sdk-switch-guide.md)。
16
17
18## 接口说明
19
20更多API说明请参见[API参考](../reference/apis/js-apis-window.md)。
21
22| 实例名            | 接口名                                                       | 描述                                                         |
23| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
24| window静态方法    | createWindow(config: Configuration, callback: AsyncCallback\<Window>): void | 创建子窗口或系统窗口。<br/>-`config`:创建窗口时的参数。     |
25| Window            | resize(width: number, height: number, callback: AsyncCallback&lt;void&gt;): void | 改变当前窗口大小。                                           |
26| Window            | moveWindowTo(x: number, y: number, callback: AsyncCallback&lt;void&gt;): void | 移动当前窗口位置。                                           |
27| Window            | SetUIContent(path: string, callback: AsyncCallback&lt;void&gt;): void | 为当前窗口加载具体页面。                                     |
28| Window            | showWindow(callback: AsyncCallback\<void>): void             | 显示当前窗口。                                               |
29| Window            | on(type: 'touchOutside', callback: Callback&lt;void&gt;): void | 开启本窗口区域外的点击事件的监听。                           |
30| Window            | hide (callback: AsyncCallback\<void>): void                  | 隐藏当前窗口。此接口为系统接口。                             |
31| Window            | destroyWindow(callback: AsyncCallback&lt;void&gt;): void     | 销毁当前窗口。                                               |
32| Window            | getTransitionController(): TransitionController              | 获取窗口属性转换控制器。此接口为系统接口。                   |
33| TransitionContext | completeTransition(isCompleted: boolean): void               | 设置属性转换的最终完成状态。该函数需要在动画函数[animateTo()](../reference/arkui-ts/ts-explicit-animation.md)执行后设置。此接口为系统接口。 |
34| Window            | showWithAnimation(callback: AsyncCallback\<void>): void      | 显示当前窗口,过程中播放动画。此接口为系统接口。             |
35| Window            | hideWithAnimation(callback: AsyncCallback\<void>): void      | 隐藏当前窗口,过程中播放动画。此接口为系统接口。             |
36
37## 系统窗口的开发
38
39本文以音量条窗口为例,介绍系统窗口的基本开发和管理步骤。
40
41### 开发步骤
42
43
441. 创建系统窗口。
45
46   在[ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md)下,使用`window.createWindow`接口创建音量条系统窗口。
47
482. 操作或设置系统窗口的属性。
49
50   系统窗口创建成功后,可以改变其大小、位置等,还可以根据需要设置系统窗口的背景色、亮度等属性。
51
523. 加载显示系统窗口的具体内容。
53
54   通过`SetUIContent`和`showWindow`接口加载显示音量条窗口的具体内容。
55
564. 隐藏/销毁系统窗口。
57
58   当不再需要音量条窗口时,可根据具体实现逻辑,使用`hide`接口或`destroyWindow`接口对其进行隐藏或销毁。
59
60```ts
61import ExtensionContext from '@ohos.app.ability.ServiceExtensionAbility';
62import window from '@ohos.window';
63
64export default class ServiceExtensionAbility1 extends ExtensionContext {
65    onCreate(want) {
66        globalThis.abilityWant = want;
67        // 1.创建音量条窗口。
68        let windowClass = null;
69        let config = {name: "volume", windowType: window.WindowType.TYPE_VOLUME_OVERLAY, ctx: this.context};
70        window.createWindow(config, (err, data) => {
71            if (err.code) {
72                console.error('Failed to create the volume window. Cause:' + JSON.stringify(err));
73                return;
74            }
75            console.info('Succeeded in creating the volume window.')
76            windowClass = data;
77            // 2.创建音量条窗口成功之后,可以改变其大小、位置或设置背景色、亮度等属性。
78            windowClass.moveWindowTo(300, 300, (err) => {
79                if (err.code) {
80                    console.error('Failed to move the window. Cause:' + JSON.stringify(err));
81                    return;
82                }
83                console.info('Succeeded in moving the window.');
84            });
85            windowClass.resize(500, 500, (err) => {
86                if (err.code) {
87                    console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
88                    return;
89                }
90                console.info('Succeeded in changing the window size.');
91            });
92            // 3.为音量条窗口加载对应的目标页面。
93            windowClass.setUIContent("pages/page_volume", (err) => {
94                if (err.code) {
95                    console.error('Failed to load the content. Cause:' + JSON.stringify(err));
96                    return;
97                }
98                console.info('Succeeded in loading the content.');
99                // 3.显示音量条窗口。
100                windowClass.showWindow((err) => {
101                    if (err.code) {
102                        console.error('Failed to show the window. Cause:' + JSON.stringify(err));
103                        return;
104                    }
105                    console.info('Succeeded in showing the window.');
106                });
107            });
108            // 4.隐藏/销毁音量条窗口。当不再需要音量条时,可根据具体实现逻辑,对其进行隐藏或销毁。
109            // 此处以监听音量条区域外的点击事件为例实现音量条窗口的隐藏。
110            windowClass.on('touchOutside', () => {
111                console.info('touch outside');
112                windowClass.hide((err) => {
113                    if (err.code) {
114                        console.error('Failed to hide the window. Cause: ' + JSON.stringify(err));
115                        return;
116                    }
117                    console.info('Succeeded in hidinging the window.');
118                });
119            });
120        });
121    }
122};
123```
124
125## 自定义系统窗口的显示与隐藏动画
126
127在显示系统窗口过程中,开发者可以自定义窗口的显示动画。在隐藏系统窗口过程中,开发者可以自定义窗口的隐藏动画。本文以显示和隐藏动画为例介绍主要开发步骤。
128
129### 开发步骤
130
1311. 获取窗口属性转换控制器。
132
133   通过`getTransitionController`接口获取控制器。后续的动画操作都由属性控制器来完成。
134
1352. 配置窗口显示时的动画。
136
137   通过动画函数[animateTo()](../reference/arkui-ts/ts-explicit-animation.md)配置具体的属性动画。
138
1393. 设置属性转换完成。
140
141   通过`completeTransition(true)`来设置属性转换的最终完成状态。如果传入false,则表示撤销本次转换。
142
1434. 显示或隐藏当前窗口,过程中播放动画。
144
145   调用`showWithAnimation`接口,来显示窗口并播放动画。调用`hideWithAnimation`接口,来隐藏窗口并播放动画。
146
147```ts
148import ExtensionContext from '@ohos.app.ability.ServiceExtensionAbility';
149import window from '@ohos.window';
150
151export default class ServiceExtensionAbility1 extends ExtensionContext {
152    onCreate(want) {
153        globalThis.abilityWant = want;
154        // 创建音量条窗口。
155        let windowClass = null;
156        let config = {name: "volume", windowType: window.WindowType.TYPE_VOLUME_OVERLAY, ctx: this.context};
157        window.createWindow(config, (err, data) => {
158            if (err.code) {
159                console.error('Failed to create the volume window. Cause:' + JSON.stringify(err));
160                return;
161            }
162            console.info('Succeeded in creating the volume window.')
163            windowClass = data;
164            // 以下为系统窗口显示动画的开发步骤
165            // 1. 获取窗口属性转换控制器
166            let controller = windowClass.getTransitionController();
167            // 2. 配置窗口显示时的动画
168            controller.animationForShown = (context : window.TransitionContext) => {
169                let toWindow = context.toWindow
170                // 配置动画参数
171                animateTo({
172                    duration: 1000, // 动画时长
173                    tempo: 0.5, // 播放速率
174                    curve: Curve.EaseInOut, // 动画曲线
175                    delay: 0, // 动画延迟
176                    iterations: 1, // 播放次数
177                    playMode: PlayMode.Normal, // 动画模式
178                    onFinish: ()=> {
179                        // 3. 设置属性转换完成
180                        context.completeTransition(true)
181                    }
182                }, () => {
183                    let obj : window.TranslateOptions = {
184                        x : 100.0,
185                        y : 0.0,
186                        z : 0.0
187                    }
188                    toWindow.translate(obj);
189                    console.info('toWindow translate end');
190                })
191                console.info('complete transition end');
192            }
193
194            windowClass.loadContent("pages/page_volume", (err) => {
195                if (err.code) {
196                    console.error('Failed to load the content. Cause:' + JSON.stringify(err));
197                    return;
198                }
199                console.info('Succeeded in loading the content.');
200                // 4.显示当前窗口,过程中播放动画
201                windowClass.showWithAnimation((err) => {
202                    if (err.code) {
203                        console.error('Failed to show the window with animation. Cause: ' + JSON.stringify(err));
204                        return;
205                    }
206                    console.info('Succeeded in showing the window with animation.');
207                })
208            });
209        });
210    }
211    onDestroy() {
212        let windowClass = null;
213        try {
214            windowClass = window.findWindow('volume');
215        } catch (exception) {
216            console.error('Failed to find the Window. Cause: ' + JSON.stringify(exception));
217        }
218        // 以下为系统窗口隐藏动画的开发步骤
219        // 1. 获取窗口属性转换控制器
220        let controller = windowClass.getTransitionController();
221        // 2. 配置窗口显示时的动画
222        controller.animationForHidden = (context : window.TransitionContext) => {
223            let toWindow = context.toWindow
224            // 配置动画参数
225            animateTo({
226                duration: 1000, // 动画时长
227                tempo: 0.5, // 播放速率
228                curve: Curve.EaseInOut, // 动画曲线
229                delay: 0, // 动画延迟
230                iterations: 1, // 播放次数
231                playMode: PlayMode.Normal, // 动画模式
232                onFinish: ()=> {
233                    // 3. 设置属性转换完成
234                    context.completeTransition(true)
235                    windowClass.destroyWindow((err) => {
236                        if (err.code) {
237                            console.error('Failed to destroy the window. Cause:' + JSON.stringify(err));
238                            return;
239                        }
240                        console.info('Succeeded in destroying the window.');
241                    });
242                }
243            }, () => {
244                toWindow.opacity(0.0);
245                console.info('toWindow opacity end');
246            })
247            console.info('complete transition end');
248        }
249        // 4.隐藏当前窗口,过程中播放动画
250        windowClass.hideWithAnimation((err) => {
251            if (err.code) {
252                console.error('Failed to hide the window with animation. Cause: ' + JSON.stringify(err));
253                return;
254            }
255            console.info('Succeeded in hiding the window with animation.');
256        });
257    }
258};
259```