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<void>): void | 改变当前窗口大小。 | 26| Window | moveWindowTo(x: number, y: number, callback: AsyncCallback<void>): void | 移动当前窗口位置。 | 27| Window | SetUIContent(path: string, callback: AsyncCallback<void>): void | 为当前窗口加载具体页面。 | 28| Window | showWindow(callback: AsyncCallback\<void>): void | 显示当前窗口。 | 29| Window | on(type: 'touchOutside', callback: Callback<void>): void | 开启本窗口区域外的点击事件的监听。 | 30| Window | hide (callback: AsyncCallback\<void>): void | 隐藏当前窗口。此接口为系统接口。 | 31| Window | destroyWindow(callback: AsyncCallback<void>): 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```