窗口动效是指窗口在显示、隐藏、切换过程中的过渡动画效果。为了让这些过程更加自然流畅,避免界面切换过于突兀,系统提供了过渡动画支持。同时,为满足开发者的自定义需求,系统还提供了自定义设置窗口动效的能力。
以下为支持设置自定义窗口动效的几种典型场景:
在使用startAbility()接口拉起同一应用内其他UIAbility组件时,可以通过StartOptions中WindowCreateParams配置窗口的启动动画。
目前支持将窗口启动动画配置为淡入淡出动效FADE_IN_OUT。
示例代码如下:
import { Want, StartOptions, common } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
private context = AppStorage.get('context') as common.UIAbilityContext;
openAbility():void {
let want: Want = {
deviceId: '',
bundleName: 'com.example.startabilitywithfadeinout',
abilityName: 'FadeInOutAbility',
moduleName: 'entry'
};
let options: StartOptions = {
// 传入启动动效参数
windowCreateParams: {
animationParams : { type: window.AnimationType.FADE_IN_OUT },
}
}
try {
this.context.startAbility(want, options, (err: BusinessError) => {
if (err.code) {
// 处理业务逻辑错误
console.error(`startAbility failed, code is ${err.code}, message is ${err.message}`);
return;
}
// 执行正常业务
console.info('startAbility succeed');
});
} catch (err) {
// 处理入参错误异常
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
console.error(`startAbility failed, code is ${code}, message is ${message}`);
}
}
build() {
RelativeContainer() {
Column() {
Button('startAbility').onClick(() => this.openAbility())
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center);
}
.height('100%')
.width('100%')
}
}
在自由窗口状态下,应用使用getWindowTransitionAnimation()获取主窗口转场的动画配置,当前转场动画配置不符合业务诉求时,可以使用setWindowTransitionAnimation()接口配置窗口转场时的动画,当前仅支持配置窗口销毁时的转场动画。
示例代码如下:
import { UIAbility } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
try {
// 获取主窗口
const windowClass = await windowStage.getMainWindow();
// 配置窗口销毁动画
this.setupWindowDestroyAnimation(windowClass);
// 加载页面
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
} catch (err) {
console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
}
}
private setupWindowDestroyAnimation(windowClass: window.Window): void {
try {
// 检查是否已存在销毁动画配置
const existingAnimation = windowClass.getWindowTransitionAnimation(
window.WindowTransitionType.DESTROY
);
if (existingAnimation) {
return;
}
// 配置动画
const animationConfig: window.WindowAnimationConfig = {
duration: 1000,
curve: window.WindowAnimationCurve.LINEAR,
};
const transitionAnimation: window.TransitionAnimation = {
opacity: 0.0,
config: animationConfig
};
// 设置动画
windowClass.setWindowTransitionAnimation(
window.WindowTransitionType.DESTROY,
transitionAnimation
).then(() => {
console.info('Succeeded in setting window transition animation');
}).catch((err: BusinessError) => {
console.error(`Failed to set window transition animation. Cause: ${err.message}`);
});
} catch (exception) {
console.error(`Failed to setup window animation. Cause: ${exception.message}`);
}
}
}