鸿蒙中级课程笔记3—ArkUI进阶1—属性动画与转场动画

动画概述

UI中包含开发者与设备进行交互时所看到的各种组件。

属性作为接口,用于控制组件的行为。属性值的变化,通常会引起UI的变化。

动画可在UI发生改变时,添加流畅的过渡效果。如果不加入动画,属性将在一瞬间完成变化。造成突兀感的同时,容易导致用户失去视觉焦点。

动画的目的包括:

  • 使界面的过渡自然流畅。
  • 增强用户从界面获得的反馈感和互动感。
  • 在内容加载等场景中,增加用户的耐心,缓解等待带来的不适感。
  • 引导用户了解和操作设备。

在需要为UI变化添加过渡的场景,都可以使用动画,如开机、应用启动退出、下拉进入控制中心等。这些动画可向用户提供关于其操作的反馈,并有助于让用户始终关注界面。

ArkUI中提供多种动画接口(属性动画转场动画等),用于驱动属性值按照设定的动画参数,从起始值逐渐变化到终点值。尽管变化过程中参数值并非绝对的连续,而是具有一定的离散性。但由于人眼会产生视觉暂留,所以最终看到的就是一个"连续"的动画。UI的一次改变称为一个动画帧,对应一次屏幕刷新。决定动画流畅度的一个重要指标就是帧率FPS(Frame Per Second),即每秒的动画帧数,帧率越高则动画就会越流畅。ArkUI中,动画参数包含了如动画时长、动画曲线等参数。动画曲线作为主要因素,决定了属性值变化的规律。以线性动画曲线为例,在动画时长内,属性值将从起点值匀速变化到终点值。属性过快或过慢的变化,都可能带来不好的视觉感受,影响用户体验。因此动画参数特别是动画曲线,需要结合场景和曲线特点进行设计和调整。

动画接口驱动属性值按照动画参数决定的规律,从原来的状态连续过渡到新的状态,进而在UI上产生连续的视觉效果。本文将按照如下结构,提供各种动画的使用方法和注意事项,使开发者快速学习动画。

  • 属性动画:最基础的动画类型,按照动画参数逐帧驱动属性的变化,产生一帧帧的动画效果。除其中的自定义属性动画外,动画过程的驱动由系统完成,应用侧不感知动画过程。

  • 转场动画:为组件在出现和消失时添加过渡动画。为了保证动画一致性,部分接口动画曲线已内置,不支持开发者自定义。

    • 不建议在应用内使用UIAbility组合所有的界面:UIAbility是一个任务,会在多任务界面独立显示为一个卡片,UIAbility之间的跳转相当于任务之间的跳转。以应用内查看大图场景为例,不建议调用图库的UIAbility来打开图片查看大图,因为这会导致任务的跳转,图库的UIAbility也会加入多任务界面中。正确的方式是应用内构建大图组件,通过模态转场去调起大图组件,一个任务内的所有的界面都在一个UIAbility内闭环。
    • 导航转场中,应使用Navigation组件实现转场动画。过去的page+router方式在实现导航转场过程中,因为page和page之间相互独立,其联动动画效果受限。不仅容易导致页面之间的割裂,并且不支持一次开发多端部署。
  • 粒子动画:介绍粒子动画的原理及使用方法。

  • 组件动画:组件提供默认动效(如List的滑动动效)便于开发者使用,同时部分组件还支持定制化动效。

  • 动画曲线:介绍传统曲线和弹簧曲线的特点和使用方式。动画曲线影响属性值的运动规律,进而决定界面的动画效果。

  • 动画衔接:介绍如何实现动画与动画之间、手势与动画之间的自然过渡。

  • 动画效果:介绍模糊、大阴影和颜色渐变等高阶效果接口的使用方法。

  • 帧动画:系统侧提供在动画过程中的插值结果,由开发者每帧修改属性值产生动画,相比于属性动画,有可实现暂停的优点,但性能不如属性动画。

属性动画概述

属性接口(以下简称属性)包含尺寸属性、布局属性、位置属性等多种类型,用于控制组件的行为。针对当前界面上的组件,其部分属性(如位置属性)的变化会引起UI的变化。添加动画可以让属性值从起点逐渐变化到终点,从而产生连续的动画效果。为保障动画起点和终点的正确性,属性动画会将当前在标脏队列内的所有节点进行刷新。如果发现当前动画时长较长时,需要确认当前是否有额外的节点刷新。根据变化时是否能够添加动画,可以将属性分为可动画属性和不可动画属性。判断一种属性是否适合作为可动画属性主要有两个标准:

  1. 属性变化能够引起UI的变化。例如,enabled属性用于控制组件是否可以响应点击、触摸等事件,但enabled属性的变化不会引起UI的变化,因此不适合作为可动画属性。

  2. 属性在变化时适合添加动画作为过渡。例如,focusable属性决定当前组件是否可以获得焦点,当focusable属性发生变化时,应立即切换到终点值以响应用户行为,不应该加入动画效果,因此不适合作为可动画属性。

属性接口分类说明:

  • 可动画属性:

    • 系统可动画属性:

      分类 说明
      布局属性 位置、大小、内边距、外边距、对齐方式、权重等。
      仿射变换 平移、旋转、缩放、锚点等。
      背景 背景颜色、背景模糊等。
      内容 文字大小、文字颜色,图片对齐方式、模糊等。
      前景 前景颜色等。
      Overlay Overlay属性等。
      外观 透明度、圆角、边框、阴影等。
      ... ...
    • 自定义可动画属性:通过自定义属性动画机制抽象出的可动画属性。

  • 不可动画属性:zIndexfocusable等。

通常,可动画属性的参数数据类型必须具备连续性,即可以通过插值方法来填补数据点之间的空隙,达到视觉上的连续效果。但属性的参数数据类型是否能够进行插值并非决定属性是否可动画的关键因素。例如,对于设置元素水平方向布局的direction属性,其参数数据类型是枚举值。但是,由于位置属性是可动画属性,ArkUI同样支持在其属性值改变引起组件位置变化时添加动画。

对于可动画属性,系统不仅提供通用属性,还支持自定义可动画属性。

  • 系统可动画属性:组件自带的支持改变UI界面的属性接口,如位置、缩放、模糊等。

  • 自定义可动画属性:ArkUI提供@AnimatableExtend装饰器用于自定义可动画属性。开发者可从自定义绘制的内容中抽象出可动画属性,用于控制每帧绘制的内容,如自定义绘制音量图标。通过自定义可动画属性,可以为ArkUI中部分原本不支持动画的属性添加动画。

实现属性动画

通过可动画属性改变引起UI上产生的连续视觉效果,即为属性动画。属性动画是最基础易懂的动画,ArkUI提供三种动画接口animateToanimationkeyframeAnimateTo驱动组件属性按照动画曲线等动画参数进行连续的变化,产生属性动画。

说明

本章节讨论的属性动画不是狭义的属性动画接口,而是通过给定新的可动画属性终值,对属性产生动画的方式。

动画接口 作用域 原理 使用场景
animateTo 闭包内改变属性引起的界面变化。 通用函数,对闭包前界面和闭包中的状态变量引起的界面之间的差异做动画。 支持多次调用,支持嵌套。 适用对多个可动画属性配置相同动画参数的动画。 需要嵌套使用动画的场景。 如果需要实现多段动画循环的效果,建议通过设置AnimateParam的playMode和iterations属性实现,或使用keyframeAnimateTo实现。
animation 组件通过属性接口绑定的属性变化引起的界面变化。 识别组件的可动画属性变化,自动添加动画。 组件的接口调用是从下往上执行,animation只会作用于在其之上的属性调用。 组件可以根据调用顺序对多个属性设置不同的animation。 适用于对多个可动画属性配置不同参数动画的场景。
keyframeAnimateTo 多个闭包内改变属性引起的分段属性动画。 通用函数,每一段闭包中的状态变量与前一次的差异做动画。 支持多次调用,不推荐嵌套。 适用于同一属性需要做连续多个动画的场景。

使用animateTo产生属性动画

API格式:animateTo(value: AnimateParam, event: () => void): void

animateTo接口参数中,value指定AnimateParam对象(包括时长、曲线等)event为动画的闭包函数,闭包内变量改变产生的属性动画将遵循相同的动画参数。

说明

直接使用animateTo可能导致UI上下文不明确的问题,建议使用getUIContext()获取UIContext实例,并使用 UIContext实例调用绑定实例的animateTo。

代码参考实现属性动画

使用animation产生属性动画

相比于animateTo接口需要将属性修改封装在闭包中执行,animation接口无需使用闭包,只需将其加在要做动画的可动画属性后即可。animation只要检测到其绑定的可动画属性发生变化,就会自动添加属性动画,animateTo则必须在动画闭包内改变可动画属性的值从而生成动画。 代码参考实现属性动画

使用keyframeAnimateTo产生属性动画

复制代码
API说明:keyframeAnimateTo(param: KeyframeAnimateParam, keyframes: Array<KeyframeState>): void

keyframeAnimateTo接口参数中,第一个参数KeyframeAnimateParam为关键帧动画的整体参数(包括延时、播放次数、结束回调、期望帧率),第二个参数是一个数组,每一项表示一个关键帧内的动画行为;每一段动画可单独控制动画参数(包括时长、曲线等)。

在同一属性存在多段动画过程的场景,可通过在结束回调中再创建新动画实现,但写法更复杂,且每次创建新动画需要耗时,会有衔接卡顿现象。此场景更适宜用关键帧动画实现。

代码参考实现属性动画

说明

  • 在对组件位置大小变化做动画的时候,由于布局属性的改变会触发测量布局,性能开销大。而scale属性的改变不会触发测量布局,性能开销小。因此,在组件位置大小持续发生变化的场景,如跟手触发组件大小变化的场景,推荐使用scale。

  • 属性动画应该作用于始终存在的组件,对于将要出现或者将要消失的组件的动画应该使用转场动画

  • 尽量不要使用动画结束回调。属性动画是对已经发生的状态进行的动画,不需要开发者去处理结束的逻辑。如果要使用结束回调,一定要正确处理连续操作的数据管理。

  • 在设置的开发者选项中关闭过渡动画,或UIAbility从前台切换至后台,会立即执行动画结束回调。建议对此类场景进行一定的验证并避免在动画结束回调中加入时序相关的功能逻辑。

转场动画概述

转场动画是指对将要出现或消失的组件做动画,对始终出现的组件做动画应使用属性动画。转场动画主要为了让开发者从繁重的消失节点管理中解放出来,如果用属性动画做组件转场,开发者需要在动画结束回调中删除组件节点。同时,由于动画结束前已经删除的组件节点可能会重新出现,还需要在结束回调中增加对节点状态的判断。

转场动画有如下几类:

  • 出现/消失转场:对新增、消失的控件实现动画效果,是通用的基础转场效果。

  • 模态转场:新的界面覆盖在旧的界面之上的动画,旧的界面不消失,新的界面出现,如弹框就是典型的模态转场动画。

  • 共享元素转场 (一镜到底):共享元素转场是一种界面切换时对相同或者相似的元素做的一种位置和大小匹配的过渡动画效果。

  • 旋转屏动画:旋转屏动画主要分为布局切换的旋转屏动画透明度变化的旋转屏动画,旨在实现屏幕显示方向变化时的自然过渡。

  • 页面转场动画:页面的路由转场方式,可以通过在pageTransition函数中自定义页面入场和页面退场的转场动效。为了实现更好的转场效果,推荐使用导航转场模态转场

  • 导航转场:页面的路由转场方式,对应一个界面消失,另外一个界面出现的动画效果,如设置应用一级菜单切换到二级界面。

转场动画更丰富的案例参考转场动画举例

相关推荐
Miguo94well2 小时前
Flutter框架跨平台鸿蒙开发——科目一题目练习APP的开发流程
flutter·华为·harmonyos
funnycoffee1233 小时前
华为CE系列交换机,关闭密码即将过期提醒
服务器·华为·华为密码过期
数通工程师3 小时前
实操教程:华为防火墙HRP主备模式完整配置步骤
运维·服务器·网络·网络协议·tcp/ip·华为
相思难忘成疾3 小时前
华为HCIP实验-BGP路由协议的配置解析
网络·华为·智能路由器·hcip
SoraLuna3 小时前
KuiklyUI for OpenHarmony 实战 02:Kuikly 工程创建与鸿蒙运行(Mac)
macos·华为·harmonyos
wqwqweee3 小时前
Flutter for OpenHarmony 看书管理记录App实战:个人中心实现
开发语言·javascript·python·flutter·harmonyos
[H*]4 小时前
Flutter框架跨平台鸿蒙开发——TextFormField基础组件详解
flutter·华为·harmonyos
知南x5 小时前
【华为昇腾DVPP/AIPP学习篇】(3) AIPP+DVPP的使用
学习·华为
BlackWolfSky5 小时前
鸿蒙中级课程笔记3—ArkUI进阶3—给应用添加交互(手势)
笔记·华为·交互·harmonyos