动画
属性动画
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-animatorproperty-0000001478181445-V3
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。
使用:animation(value: {duration?: number, tempo?: number, curve?: string | Curve | ICurve, delay?:number, iterations: number, playMode?: PlayMode, onFinish?: () => void})
例如:Button('change size').onClick(() => {if (this.flag) {this.widthSize = 150this.heightSize = 60} else {this.widthSize = 250this.heightSize = 100}this.flag = !this.flag}).margin(30).width(this.widthSize).height(this.heightSize).animation({duration: 2000,curve: Curve.EaseOut,iterations: 3,playMode: PlayMode.Normal})
显式动画
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-explicit-animation-0000001478341181-V3
提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。
使用:animateTo(value: AnimateParam, event: () => void): void
例如:Button('change rotate angle').margin(50).rotate({ x: 0, y: 0, z: 1, angle: this.rotateAngle }).onClick(() => {animateTo({duration: 1200,curve: Curve.Friction,delay: 500,iterations: -1, // 设置-1表示动画无限循环playMode: PlayMode.Alternate,onFinish: () => {console.info('play end')}}, () => {this.rotateAngle = 90})})
转场动画
页面间转场
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-page-transition-animation-0000001477981233-V3
在全局pageTransition方法内配置页面入场和页面退场时的自定义转场动效。
例如:
// page1.ets
@Entry
@Component
struct AExample {@State scale2: number = 1@State opacity2: number = 1build() {Column() {Navigator({ target: 'pages/index', type: NavigationType.Push }) {Image($r('app.media.bg2')).width('100%').height('100%') // 图片存放在media文件夹下}}.width('100%').height('100%').scale({ x: this.scale2 }).opacity(this.opacity2)}// 自定义方式1:完全自定义转场过程的效果pageTransition() {PageTransitionEnter({ duration: 1200, curve: Curve.Linear }).onEnter((type: RouteType, progress: number) => {this.scale2 = 1this.opacity2 = progress}) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%)PageTransitionExit({ duration: 1500, curve: Curve.Ease }).onExit((type: RouteType, progress: number) => {this.scale2 = 1 - progressthis.opacity2 = 1}) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%)}
}
组件内转场
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-transition-animation-component-0000001427902496-V3
组件内转场主要通过transition属性配置转场参数,在组件插入和删除时显示过渡动效,主要用于容器组件中的子组件插入和删除时,提升用户体验(需要配合animateTo才能生效,动效时长、曲线、延时跟随animateTo中的配置)。
例如:
// xxx.ets
@Entry
@Component
struct TransitionExample {@State flag: boolean = true@State show: string = 'show'build() {Column() {Button(this.show).width(80).height(30).margin(30).onClick(() => {// 点击Button控制Image的显示和消失animateTo({ duration: 1000 }, () => {if (this.flag) {this.show = 'hide'} else {this.show = 'show'}this.flag = !this.flag})})if (this.flag) {// Image的显示和消失配置为不同的过渡效果Image($r('app.media.testImg')).width(300).height(300).transition({ type: TransitionType.Insert, scale: { x: 0, y: 1.0 } }).transition({ type: TransitionType.Delete, rotate: { angle: 180 } })}}.width('100%')}
}
图片完全显示时:
图片消失时配置顺时针旋转180°的过渡效果:
图片完全消失时:
图片显示时配置横向放大一倍的过渡效果:
共享元素转场
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-transition-animation-shared-elements-0000001428061776-V3
当路由进行切换时,可以通过设置组件的 sharedTransition 属性将该元素标记为共享元素并设置对应的共享元素转场动效。
例如:
// xxx.ets
@Entry
@Component
struct SharedTransitionExample {@State active: boolean = falsebuild() {Column() {Navigator({ target: 'pages/PageB', type: NavigationType.Push }) {Image($r('app.media.ic_health_heart')).width(50).height(50).sharedTransition('sharedImage', { duration: 800, curve: Curve.Linear, delay: 100 })}.padding({ left: 20, top: 20 }).onClick(() => {this.active = true})}}
}// PageB.ets
@Entry
@Component
struct pageBExample {build() {Stack() {Image($r('app.media.ic_health_heart')).width(150).height(150).sharedTransition('sharedImage', { duration: 800, curve: Curve.Linear, delay: 100 })}.width('100%').height('100%')}
}
路径动画
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-motion-path-animation-0000001427584908-V3
设置组件进行位移动画时的运动路径。
例如:
// xxx.ets
@Entry
@Component
struct MotionPathExample {@State toggle: boolean = truebuild() {Column() {Button('click me').margin(50)// 执行动画:从起点移动到(300,200),再到(300,500),再到终点.motionPath({ path: 'Mstart.x start.y L300 200 L300 500 Lend.x end.y', from: 0.0, to: 1.0, rotatable: true }).onClick(() => {animateTo({ duration: 4000, curve: Curve.Linear }, () => {this.toggle = !this.toggle // 通过this.toggle变化组件的位置})})}.width('100%').height('100%').alignItems(this.toggle ? HorizontalAlign.Start : HorizontalAlign.Center)}
}
全局UI方法
弹窗
警告弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-alert-dialog-box-0000001478341185-V3
显示警告弹窗组件,可设置文本内容与响应回调。
例如:
// xxx.ets
@Entry
@Component
struct AlertDialogExample {build() {Column({ space: 5 }) {Button('one button dialog').onClick(() => {AlertDialog.show({title: 'title',message: 'text',autoCancel: true,alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: -20 },gridCount: 3,confirm: {value: 'button',action: () => {console.info('Button-clicking callback')}},cancel: () => {console.info('Closed callbacks')}})}).backgroundColor(0x317aff)Button('two button dialog').onClick(() => {AlertDialog.show({title: 'title',message: 'text',autoCancel: true,alignment: DialogAlignment.Bottom,gridCount: 4,offset: { dx: 0, dy: -20 },primaryButton: {value: 'cancel',action: () => {console.info('Callback when the first button is clicked')}},secondaryButton: {value: 'ok',action: () => {console.info('Callback when the second button is clicked')}},cancel: () => {console.info('Closed callbacks')}})}).backgroundColor(0x317aff)}.width('100%').margin({ top: 5 })}
}
列表选择弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-action-sheet-0000001478061737-V3
使用:show(value: { title: string | Resource, message: string | Resource, confirm?: {value: string | Resource, action:() => void}, cancel?:()=>void, sheets: Array<SheetInfo>, autoCancel?:boolean, alignment?: DialogAlignment, offset?: { dx: number | string | Resource; dy: number | string | Resource } })
例如:
@Entry
@Component
struct ActionSheetExample {build() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Button('Click to Show ActionSheet').onClick(() => {ActionSheet.show({title: 'ActionSheet title',message: 'message',autoCancel: true,confirm: {value: 'Confirm button',action: () => {console.log('Get Alert Dialog handled')}},cancel: () => {console.log('actionSheet canceled')},alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: -10 },sheets: [{title: 'apples',action: () => {console.log('apples')}},{title: 'bananas',action: () => {console.log('bananas')}},{title: 'pears',action: () => {console.log('pears')}}]})})}.width('100%').height('100%')}
}
自定义弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-custom-dialog-box-0000001477981237-V3
通过CustomDialogController类显示自定义弹窗。使用弹窗组件时,可优先考虑自定义弹窗,便于自定义弹窗的样式与内容。
使用:CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, offset?: Offset, customStyle?: boolean, gridCount?: number})
例如:
// xxx.ets
@CustomDialog
struct CustomDialogExample {@Link textValue: string@Link inputValue: stringcontroller: CustomDialogController// 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在最后cancel: () => voidconfirm: () => voidbuild() {Column() {Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%').onChange((value: string) => {this.textValue = value})Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })Flex({ justifyContent: FlexAlign.SpaceAround }) {Button('cancel').onClick(() => {this.controller.close()this.cancel()}).backgroundColor(0xffffff).fontColor(Color.Black)Button('confirm').onClick(() => {this.inputValue = this.textValuethis.controller.close()this.confirm()}).backgroundColor(0xffffff).fontColor(Color.Red)}.margin({ bottom: 10 })}// dialog默认的borderRadius为24vp,如果需要使用border属性,请和borderRadius属性一起使用。}
}@Entry
@Component
struct CustomDialogUser {@State textValue: string = ''@State inputValue: string = 'click me'dialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogExample({cancel: this.onCancel,confirm: this.onAccept,textValue: $textValue,inputValue: $inputValue}),cancel: this.existApp,autoCancel: true,alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: -20 },gridCount: 4,customStyle: false})// 在自定义组件即将析构销毁时将dialogController置空aboutToDisappear() {this.dialogController = undefined // 将dialogController置空}onCancel() {console.info('Callback when the first button is clicked')}onAccept() {console.info('Callback when the second button is clicked')}existApp() {console.info('Click the callback in the blank area')}build() {Column() {Button(this.inputValue).onClick(() => {if (this.dialogController != undefined) {this.dialogController.open()}}).backgroundColor(0x317aff)}.width('100%').margin({ top: 5 })}
}
日期滑动选择器弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-datepicker-dialog-0000001427902500-V3
根据指定的日期范围创建日期滑动选择器,展示在弹窗上。
使用:show(options?: DatePickerDialogOptions)
例如:DatePickerDialog.show({start: new Date("2000-1-1"),end: new Date("2100-12-31"),selected: this.selectedDate,onAccept: (value: DatePickerResult) => {// 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期this.selectedDate.setFullYear(value.year, value.month, value.day)console.info("DatePickerDialog:onAccept()" + JSON.stringify(value))},onCancel: () => {console.info("DatePickerDialog:onCancel()")},onChange: (value: DatePickerResult) => {console.info("DatePickerDialog:onChange()" + JSON.stringify(value))}})
时间滑动选择器弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-timepicker-dialog-0000001428061780-V3
以24小时的时间区间创建时间滑动选择器,展示在弹窗上。
使用:TimePickerDialog.show(options?: TimePickerDialogOptions)
例如:TimePickerDialog.show({selected: this.selectTime,onAccept: (value: TimePickerResult) => {// 设置selectTime为按下确定按钮时的时间,这样当弹窗再次弹出时显示选中的为上一次确定的时间this.selectTime.setHours(value.hour, value.minute)console.info("TimePickerDialog:onAccept()" + JSON.stringify(value))},onCancel: () => {console.info("TimePickerDialog:onCancel()")},onChange: (value: TimePickerResult) => {console.info("TimePickerDialog:onChange()" + JSON.stringify(value))}})
文本滑动选择器弹窗
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-textpicker-dialog-0000001427584912-V3
根据指定的选择范围创建文本选择器,展示在弹窗上。
使用:TextPickerDialog.show(options?: TextPickerDialogOptions)
例如:TextPickerDialog.show({range: this.fruits,selected: this.select,onAccept: (value: TextPickerResult) => {// 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项this.select = value.indexconsole.info("TextPickerDialog:onAccept()" + JSON.stringify(value))},onCancel: () => {console.info("TextPickerDialog:onCancel()")},onChange: (value: TextPickerResult) => {console.info("TextPickerDialog:onChange()" + JSON.stringify(value))}})
菜单(下拉选择菜单)
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-menu-0000001427744864-V3
在页面范围内关闭通过bindContextMenu属性绑定的菜单。
例如:
// xxx.ets
@Entry
@Component
struct Index {@Builder MenuBuilder() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Button('Test ContextMenu1')Divider().strokeWidth(2).margin(5).color(Color.Black)Button('Test ContextMenu2')Divider().strokeWidth(2).margin(5).color(Color.Black)Button('Test ContextMenu3')}.width(200).height(160)}build() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Column() {Text("Test ContextMenu").fontSize(20).width('100%').height(500).backgroundColor(0xAFEEEE).textAlign(TextAlign.Center)}.bindContextMenu(this.MenuBuilder, ResponseType.LongPress).onDragStart(()=>{// 拖拽时关闭菜单ContextMenu.close()})}.width('100%').height('100%')}
}