0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙ArkUI开发-属性动画的使用

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-01-25 17:37 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1 概述

属性动画,是最为基础的动画,其功能强大、使用场景多,应用范围较广。常用于如下场景中:

  • 一、页面布局发生变化。例如添加、删除部分组件元素。
  • 二、页面元素的可见性和位置发生变化。例如显示或者隐藏部分元素,或者将部分元素从一端移动到另外一端。
  • 三、页面中图形图片元素动起来。例如使页面中的静态图片动起来。

简单来说,属性动画是组件的通用属性发生改变时而产生的属性渐变效果。如下图所示,其原理是,当组件的通用属性发生改变时,组件状态由初始状态逐渐变为结束状态的过程中,会创建多个连续的中间状态,逐帧播放后,就会形成属性渐变效果,从而形成动画。

属性动画的使用方式也非常简单,只需要给组件(包括基础组件和容器组件)添加animation属性,并设置好参数,如下代码所示:

Image($r('app.media.image1'))   
   .animation({   
      duration: 1000,    
      tempo: 1.0,    
      delay: 0,    
      curve: Curve.Linear,    
      playMode: PlayMode.Normal,    
      iterations: 1  
   })

2 创建属性动画页面

如下图所示,在该下拉刷新动画场景中,一共有6个属性动画。头部中的五个图标的移动放大动画中,每个图标都是单独的一个动画,其共同组合成一个刷新等待动画。最后是下方组件上移的一个移动动画。为方便理解,图中下方的内容将以图片来代替实际应用的功能页面。

图2-1 :示例动画

该6个属性动画创建方式类似,以五个图标放大移动动画的为例来讲解如何创建属性动画。

首先,创建一个头部刷新组件RefreshAnimHeader,在其中自定义一个图标组件AttrAnimIcons,用Image组件将资源图标引入,并设置好样式,如下所示:

@Component
export default struct RefreshAnimHeader {
  ...
  @Builder AttrAnimIcons(iconItem) {  
    Image(iconItem.imgRes)    
      .width(this.iconWidth)    
      .position({ x: iconItem.posX })    
      .objectFit(ImageFit.Contain)    
      .animation({      
        duration: 2000,      
        tempo: 3.0,      
        delay: iconItem.delay,      
        curve: Curve.Linear,      
        playMode: PlayMode.Alternate,      
        iterations: -1
     })
  }
  ...
}

然后在build方法中使用Row容器组件,将自定义的图标组件引入,并设置好样式,同时定义组件状态iconWidth,添加onApper事件,修改iconWidth的值,使其从30变为100,触发UI状态更新。

@Component
export default struct RefreshAnimHeader {
  ...
  @State iconWidth: number = 30;
  private onStateCheck() {  
    if (this.state === RefreshState.REFRESHING) {    
      this.iconWidth = 100;  
    } else {    
      this.iconWidth = 30;  
    }
  }
  build() {  
    Row() {    
      ForEach(CommonConstants.REFRESH_HEADER_FEATURE, (iconItem) = > {     
        this.AttrAnimIcons(iconItem)    
      }, item = > item.toString())  
    }  
     .width("100%")  
     .height("100%")  
     .onAppear(() = > {    
       this.onStateCheck();
     })
  }
}

运行代码,即可看到五个图标的移动放大动画效果。

1、animation属性作用域。animation自身也是组件的一个属性,其作用域为animation之前。即产生属性动画的属性须在animation之前声明,其后声明的将不会产生属性动画。以示例中的五个图标动画为例,我们期望产生动画的属性为Image组件的width属性,故该属性width需在animation属性之前声明。如果将该属性width在animation之后声明,则不会产生动画效果。

2、产生属性动画的属性变化时需触发UI状态更新。在本示例中,产生动画的属性width,其值是通过变量iconWidth从30变为100,故该变量iconWidth的改变需触发UI状态更新。

3、产生属性动画的属性本身需满足一定的要求,并非任何属性都可以产生属性动画。目前支持的属性包括width、height、position、opacity、backgroundColor、scale、rotate、translate等

3 属性动画参数调整

属性动画中animation的参数如下:

属性名称属性类型默认值描述
durationnumber1000动画时长,单位为毫秒,默认时长为1000毫秒。
temponumber1.0动画的播放速度,值越大动画播放越快,值越小播放越慢,为0时无动画效果。
curveCurveCurve.Linear动画变化曲线,默认曲线为线性。
delaynumber0延时播放时间,单位为毫秒,默认不延时播放。
iterationsnumber1播放次数,默认一次,设置为-1时表示无限次播放。
playModePlayModePlayMode.Normal设置动画播放模式,默认播放完成后重头开始播放。
onFinishfunction-动画播放结束时回调该函数。

其中变化曲线curve枚举值为:

名称描述
Linear表示动画从头到尾的速度都是相同的。
Ease表示动画以低速开始,然后加快,在结束前变慢,CubicBezier(0.25, 0.1, 0.25, 1.0)。
EaseIn表示动画以低速开始,CubicBezier(0.42, 0.0, 1.0, 1.0)。
EaseOut表示动画以低速结束,CubicBezier(0.0, 0.0, 0.58, 1.0)。
EaseInOut表示动画以低速开始和结束,CubicBezier(0.42, 0.0, 0.58, 1.0)。
FastOutSlowIn标准曲线,cubic-bezier(0.4, 0.0, 0.2, 1.0)。
LinearOutSlowIn减速曲线,cubic-bezier(0.0, 0.0, 0.2, 1.0)。
FastOutLinearIn加速曲线,cubic-bezier(0.4, 0.0, 1.0, 1.0)。
ExtremeDeceleration急缓曲线,cubic-bezier(0.0, 0.0, 0.0, 1.0)。
Sharp锐利曲线,cubic-bezier(0.33, 0.0, 0.67, 1.0)。
Rhythm节奏曲线,cubic-bezier(0.7, 0.0, 0.2, 1.0)。
Smooth平滑曲线,cubic-bezier(0.4, 0.0, 0.4, 1.0)。
Friction阻尼曲线,CubicBezier(0.2, 0.0, 0.2, 1.0)。

播放模式playMode枚举值为:

名称描述
Normal动画按正常播放。
Reverse动画反向播放。
Alternate动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。
AlternateReverse动画在奇数次(1、3、5...)反向播放,在偶数次(2、4、6...)正向播放。

本文以参数delay和onFinish为例来演示和讲解属性动画的参数调整。其他参数的效果可自行尝试。

延时播放时间delay的设置

在单个的组件元素的属性动画中,一般不设置参数delay的值。而在需要设置时,往往是需要在动画开始前做一些准备工作,具体依场景而定,本文在此不讨论。

在由多个组件元素的属性动画组合的动画中,例如示例动画中的五个图标的属性动画组合而成的刷新等待动画,通过设置参数delay的值,可以使各个组件元素之间按照一定的秩序依次播放,形成跌宕起伏、鳞次栉比的动画效果。在此场景中,该值的大小又与duration相关联。

该如何设置各个图标的参数delay的值呢?

在设置delay值之前,我们先理解一个概念:延时间距。其意思是两个图标组件的延时参数delay的差值,即:delay2-delay1=延时间距。要想实现五个图标之间以良好的秩序先后移动放大,各个图标之间的延时间距是一样的,例如延时间距为100ms时,此五个图标的延时delay可以分别设置为100ms、200ms、300ms、400ms、500ms。

在实际开发场景中,我们该如何确定延时间距呢?

在此有个经验可以参考:在延时间距不超过动画时长duration时,总延时间距越接近duration,秩序性越好。其中,总延时间距为延时间距与图标数量的乘积,即:延时间距*图标数量=总延时间距。

故此,我们在设置参数delay时,需要确定动画时长duration的值。该值默认为1000ms,具体时长可依据具体的业务需要来决定。

在本示例动画中,图标动画时长duration为2000ms,故延时间距为2000ms/5=400ms,五个图标的延时参数delay可分别设置为400ms、800ms、1200ms、1600ms、2000ms。其效果如示例图所示,图标先后秩序明显,视觉效果良好。

onFinish回调函数的使用

参数onFinish与参数iterations有关。当参数iterations播放结束时,会调用onFinish函数来进行后续的业务处理。例如提示动画播放结束。

Image(iconItem.imgRes)
  .width(this.iconWidth)
  .position({ x: iconItem.posX })
  .objectFit(ImageFit.Contain)
  .animation({
    duration: 2000,
    tempo: 3.0,
    delay: iconItem.delay,
    curve: Curve.Linear,
    playMode: PlayMode.Normal,
    iterations: 1,
    onFinish: () = > {      
      prompt.showToast({ message:"动画播放结束!!!" })
    }
  })

当iterations设置为-1时,表示无限次播放,则onFinish回调函数不会被调用。

4 关闭属性动画页面

此处需要将关闭属性动画区别开来:

  • 属性动画关闭,是指动画播放结束,但是动画组件依然存在并显示在页面上。
  • 关闭属性动画页面,是指将动画的组件删除或者隐藏起来。

在本示例动画中,指将头部刷新组件RefreshAnimHeader隐藏起来。该如何实现呢?

首先,在组件RefreshAnimHeader中添加变量state,并用@Consume监听其值的变化,同时添加条件渲染逻辑,根据state的值来判断是否需要关闭。当state变为IDLE状态时,表示需要关闭属性动画页面。

@Component
export default struct RefreshAnimHeader {  
  @Consume(RefreshConstants.REFRESH_STATE_TAG) @Watch('onStateCheck') state: RefreshState;
  build() {
    Row() {
      if (this.state !== RefreshState.IDLE) { // start or stop animation when idle state.
        ForEach(CommonConstants.REFRESH_HEADER_FEATURE, (iconItem) = > {
          this.AttrAnimIcons(iconItem)
        }, item = > item.toString()}
      }
    }
    .width(CommonConstants.FULL_LENGTH)
    .height(CommonConstants.FULL_LENGTH)
    .onAppear(() = > {
      this.onStateCheck();
    })
  }
}

其次,在本示例中,通过下方图片的上移属性动画来关闭刷新组件RefreshAnimHeader。在组件RefreshComponent中,通过@Consume与组件RefreshAnimHeader的@Consume进行间接绑定,修改state变量的值为IDLE状态即可关闭属性动画页面。

@Component
export default struct RefreshComponent {
  @Consume(RefreshConstants.REFRESH_STATE_TAG) @Watch('onStateChanged') state: RefreshState;
  build() {
    List({ scroller: this.listController }) {
      ListItem() {
         ...
      }
  }  
  .animation({
    curve: Curve.Smooth,
    duration: RefreshConstants.REFRESH_HEADER_ANIM_DURATION,
    playMode: PlayMode.Normal,
    onFinish: () = > {
      if (this.headerOffset === -RefreshConstants.REFRESH_HEADER_HEIGHT) {
        this.state = RefreshState.IDLE;
      }
    }
  })
}

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙
    +关注

    关注

    60

    文章

    2858

    浏览量

    45354
  • OpenHarmony
    +关注

    关注

    31

    文章

    3926

    浏览量

    20720
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【M-K1HSE开发板免费体验】相关源码之阅读和分析1-使用XComponent + Vsync 实现自定义动画

    :收到 Vsync 信号后提交新帧到屏幕,保证流畅性。 主线程无关:即使主线程因复杂布局或逻辑阻塞,动画仍能持续流畅运行。 先看看这个项目: 这是这个项目的结构,文件。这是一个非常典型的华为鸿蒙
    发表于 09-03 16:05

    【HarmonyOS next】ArkUI-X新闻热搜聚合App【进阶】

    通过ArkUI-X将鸿蒙下的新闻热搜聚合App转换为iOS 一、项目背景与技术选型 1.1 项目概述 本案例基于鸿蒙(HarmonyOS)开发的聚合热搜热榜应用,通过调用韩小韩博客提供
    发表于 06-28 21:43

    【HarmonyOS next】ArkUI-X休闲益智儿童拼图【进阶】

    项目,我们验证了ArkUI-X框架的强大跨端能力。无论是华为的鸿蒙系统,还是iOS平台,都能保持90%以上代码复用率,真正实现了\"一次开发,多端部署\"的理想状态。期待
    发表于 06-28 21:41

    ArkUI介绍

    ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面
    发表于 06-24 06:41

    ArkUI-X案例解析

    。 最终实现效果 harmonyos包展示效果,存在tab页“溪村挑战赛” arkuix包展示效果,没有tab页“溪村挑战赛” 使用支持跨平台的UI控件、属性、方法进行跨平台开发 在音乐专辑中,当音乐
    发表于 06-23 22:40

    ArkUI-X应用工程结构说明

    简介 本文档配套ArkUI-X,将OpenHarmony ArkUI开发框架扩展到不同的OS平台,比如Android和iOS平台,让开发者基于Ark
    发表于 06-19 23:11

    ArkUI-X跨平台技术落地-华为运动健康(一)

    开发工作量以及保证体验一致性,对于运动健康App而言,显得尤为重要。作为鸿蒙NEXT系统生态中的重要一员,ArkUI-X框架是我们跨平台技术方案的首选。结合当前运动健康三端现状,具体采取如下跨平台技术
    发表于 06-18 22:53

    鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析

    鸿蒙Web性能优化宝藏指南!那些官方没明说的实战技巧 各位鸿蒙开发者好!最近在排查Web页面卡顿时,意外在HarmonyOS开发者文档里挖到性能优化的宝藏案例!这些实战经验藏在「应用质
    发表于 06-12 17:09

    鸿蒙5开发宝藏案例分享---分析帧率问题

    鸿蒙性能优化宝藏:帧率问题实战案例解析 嘿,各位鸿蒙开发者! 今天分享一个开发中的大发现——鸿蒙官方文档里藏着一堆超实用的性能优化案例!这些
    发表于 06-12 17:07

    鸿蒙5开发宝藏案例分享---点击完成时延分析

    ?** 鸿蒙完成时延优化实战指南:让你的应用丝滑如飞!** 在移动端开发中, 完成时延就是用户体验的生命线 !今天带你深入鸿蒙完成时延优化,揭秘官方文档中的宝藏技巧,让你的应用告别卡顿,流畅起飞
    发表于 06-12 17:03

    鸿蒙5开发宝藏案例分享---性能体验设计

    }) .opacity(0.8) } 官方转场动效示例 动效设计铁律 : 启动动效≤1100ms 属性变化使用贝塞尔曲线(别用linear!) 避免背景色突变(用渐变动画过渡) 四、性能检测神器
    发表于 06-12 16:45

    Kuikly鸿蒙版正式开源 —— 揭秘卓越性能适配之旅

    ArkUI 来编写的,UI组件由数据和UI描述组成,UI更新只能通过修改其绑定的数据来实现。渲染层怎样驱动声明式的ArkUI成为了鸿蒙版适配的第一个问题。 初步解决方案:统一Builder入口,全量
    发表于 06-04 16:46

    ArkUI-X跨平台框架接入指南

    ArkUI跨平台框架(ArkUI-X)进一步将ArkUI开发框架扩展到了多个OS平台:目前支持OpenHarmony、Android、 iOS,后续会逐步增加更多平台支持。
    发表于 05-18 18:21

    DialogHub上线OpenHarmony开源社区,高效开发鸿蒙应用弹窗

    作为鸿蒙应用开发者,在使用ArkUI现有能力进行弹窗开发时,总会遇到一些让人纠结的交互问题:应用内进行消息提示时,既要求消息内容支持图文混排,又要求弹窗本身不能打断用户交互(页面滑动、
    发表于 04-03 17:30

    【「极速探索HarmonyOS NEXT 」阅读体验】 初印象:一本纯血鸿蒙应用开发入门的好书

    非常有幸的于近日收到了电子发烧友寄来的《 极速探索HarmonyOS NEXT **** 纯血鸿蒙应用开发实践》这本由清华大学出版社出版的一本纯血鸿蒙应用开发学习的一本好书。 书籍一共
    发表于 03-04 12:41