• 鸿蒙App动画、弹窗


    动画

    属性动画

    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 = 150
            this.heightSize = 60
          } else {
            this.widthSize = 250
            this.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
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    显式动画

    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
          })
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    转场动画

    页面间转场

    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 = 1
    
      build() {
        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 = 1
            this.opacity2 = progress
          }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%)
        PageTransitionExit({ duration: 1500, curve: Curve.Ease })
          .onExit((type: RouteType, progress: number) => {
            this.scale2 = 1 - progress
            this.opacity2 = 1
          }) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述
    在这里插入图片描述

    组件内转场

    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%')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    图片完全显示时:
    在这里插入图片描述
    图片消失时配置顺时针旋转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 = false
    
      build() {
        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%')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    路径动画

    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 = true
    
      build() {
        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)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    全局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 })
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    在这里插入图片描述

    列表选择弹窗

    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, autoCancel?:boolean, alignment?: DialogAlignment, offset?: { dx: number | string | Resource; dy: number | string | Resource } })
    
    • 1

    例如:

    @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%')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    在这里插入图片描述

    自定义弹窗

    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})
    
    • 1

    例如:

    // xxx.ets
    @CustomDialog
    struct CustomDialogExample {
      @Link textValue: string
      @Link inputValue: string
      controller: CustomDialogController
      // 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在最后
      cancel: () => void
      confirm: () => void
    
      build() {
        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.textValue
                this.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 })
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    在这里插入图片描述

    日期滑动选择器弹窗

    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))
            }
          })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    时间滑动选择器弹窗

    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))
            }
          })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    文本滑动选择器弹窗

    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.index
                console.info("TextPickerDialog:onAccept()" + JSON.stringify(value))
              },
              onCancel: () => {
                console.info("TextPickerDialog:onCancel()")
              },
              onChange: (value: TextPickerResult) => {
                console.info("TextPickerDialog:onChange()" + JSON.stringify(value))
              }
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    菜单(下拉选择菜单)

    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%')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

  • 相关阅读:
    Android使用Banner框架实现轮播图
    新中新身份证阅读器驱动下载sdk DKQ-A16D
    社区动态——恭喜海豚调度中国区用户组新晋 9 枚“社群管理员”
    【机器学习】DBSCAN聚类算法的理论/实现与调参
    南卡和UHB这两款电容笔哪一款更值得入手?高性价比平替电容笔对比
    阅读笔记——A Frustratingly Easy Approach for Entity and Relation Extraction
    Web攻防04_MySQL注入_盲注
    RflySim | 滤波器设计实验二
    数字工厂中的SCADA(数据采集与监控系统)
    【Git】Git 学习笔记_操作本地仓库
  • 原文地址:https://blog.csdn.net/cmwly/article/details/136454735