鸿蒙应用开发:属性动画的实践
目录 前言动画概述关于属性动画实现属性动画自定义属性动画结束语 前言 在移动互联网快速发展的今天,应用的交互体验和视觉效果已成为用户选择的重要考量因素。HarmonyOS作为新一代的智能终端操作系统,不仅为开发者提供了丰富的开发工具和组件,更在动画效果上进行了深度的优化和升级。属性动画,作为鸿蒙应用开发中的一大亮点,其强大的功能
目录
- 前言
- 动画概述
- 关于属性动画
- 实现属性动画
- 自定义属性动画
- 结束语
前言
在移动互联网快速发展的今天,应用的交互体验和视觉效果已成为用户选择的重要考量因素。HarmonyOS作为新一代的智能终端操作系统,不仅为开发者提供了丰富的开发工具和组件,更在动画效果上进行了深度的优化和升级。属性动画,作为鸿蒙应用开发中的一大亮点,其强大的功能和灵活性使得应用的交互体验得到了质的飞跃。本文将深入解析鸿蒙应用开发中的属性动画实践,从动画概述、属性动画的基本概念、实现方法、自定义动画以及实际开发中的应用实例等多个方面进行详细介绍。
动画概述
UI动画通过平滑的属性变化提升用户体验,增强互动感和操作反馈。ArkUI提供属性动画、转场动画、组件动画等,支持定制化动效,如模糊、阴影等高阶效果。动画参数(时长、曲线)影响流畅度,帧率(FPS)决定视觉顺滑程度。推荐使用Navigation组件实现导航转场,保持任务内界面闭环,避免使用UIAbility组合所有界面,确保动画一致性与性能优化。
关于属性动画
属性接口用于控制界面组件的行为,分为可动画和不可动画属性。可动画属性的变化能引起UI变化并适合添加动画过渡,如布局、仿射变换、背景、内容、外观等属性;这些属性的数据类型通常具有连续性,可通过插值实现平滑动画效果。不可动画属性包括像zIndex、focusable等,它们的变化不适合或不需要动画。系统支持自定义可动画属性,开发者利用 @AnimatableExtend 装饰器从自定义绘制内容中抽象出新属性,甚至为传统上不支持动画的属性增加动画能力。例如,尽管direction属性基于枚举值,但因其影响组件位置,故也能支持动画。总体而言,这种机制增强了用户界面的动态性和交互体验。
实现属性动画
ArkUI提供两种属性动画接口animateTo和animation驱动组件属性按照动画曲线等动画参数进行连续的变化,产生属性动画。
使用animateTo产生属性动画
animateTo(value: AnimateParam, event: () => void): void
animateTo接口参数中,value指定AnimateParam对象(包括时长、Curve等)event为动画的闭包函数,闭包内变量改变产生的属性动画将遵循相同的动画参数。
实现案例:
import { curves } from '@kit.ArkUI';
@Entry
@Component
struct AnimateToDemo {
@State animate: boolean = false;
// 第一步: 声明相关状态变量
@State rotateValue: number = 0; // 组件一旋转角度
@State translateX: number = 0; // 组件二偏移量
@State opacityValue: number = 1; // 组件二透明度
// 第二步:将状态变量设置到相关可动画属性接口
build() {
Row() {
// 组件一
Column() {
}
.rotate({ angle: this.rotateValue })
.backgroundColor('#317AF7')
.justifyContent(FlexAlign.Center)
.width(100)
.height(100)
.borderRadius(30)
.onClick(() => {
this.getUIContext()?.animateTo({ curve: curves.springMotion() }, () => {
this.animate = !this.animate;
// 第三步:闭包内通过状态变量改变UI界面
// 这里可以写任何能改变UI的逻辑比如数组添加,显隐控制,系统会检测改变后的UI界面与之前的UI界面的差异,对有差异的部分添加动画
// 组件一的rotate属性发生变化,所以会给组件一添加rotate旋转动画
this.rotateValue = this.animate ? 90 : 0;
// 组件二的透明度发生变化,所以会给组件二添加透明度的动画
this.opacityValue = this.animate ? 0.6 : 1;
// 组件二的translate属性发生变化,所以会给组件二添加translate偏移动画
this.translateX = this.animate ? 50 : 0;
})
})
// 组件二
Column() {
}
.justifyContent(FlexAlign.Center)
.width(100)
.height(100)
.backgroundColor('#D94838')
.borderRadius(30)
.opacity(this.opacityValue)
.translate({ x: this.translateX })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
使用animation产生属性动画,比于animateTo接口需要把要执行动画的属性的修改放在闭包中,animation接口无需使用闭包,把animation接口加在要做属性动画的可动画属性后即可。animation只要检测到其绑定的可动画属性发生变化,就会自动添加属性动画,animateTo则必须在动画闭包内改变可动画属性的值从而生成动画。
实现案例:
import { curves } from '@kit.ArkUI';
@Entry
@Component
struct AnimationDemo {
@State animate: boolean = false;
// 第一步: 声明相关状态变量
@State rotateValue: number = 0; // 组件一旋转角度
@State translateX: number = 0; // 组件二偏移量
@State opacityValue: number = 1; // 组件二透明度
// 第二步:将状态变量设置到相关可动画属性接口
build() {
Row() {
// 组件一
Column() {
}
.opacity(this.opacityValue)
.rotate({ angle: this.rotateValue })
// 第三步:通过属性动画接口开启属性动画
.animation({ curve: curves.springMotion() })
.backgroundColor('#317AF7')
.justifyContent(FlexAlign.Center)
.width(100)
.height(100)
.borderRadius(30)
.onClick(() => {
this.animate = !this.animate;
// 第四步:闭包内通过状态变量改变UI界面
// 这里可以写任何能改变UI的逻辑比如数组添加,显隐控制,系统会检测改变后的UI界面与之前的UI界面的差异,对有差异的部分添加动画
// 组件一的rotate属性发生变化,所以会给组件一添加rotate旋转动画
this.rotateValue = this.animate ? 90 : 0;
// 组件二的translate属性发生变化,所以会给组件二添加translate偏移动画
this.translateX = this.animate ? 50 : 0;
// 父组件column的opacity属性有变化,会导致其子节点的透明度也变化,所以这里会给column和其子节点的透明度属性都加动画
this.opacityValue = this.animate ? 0.6 : 1;
})
// 组件二
Column() {
}
.justifyContent(FlexAlign.Center)
.width(100)
.height(100)
.backgroundColor('#D94838')
.borderRadius(30)
.opacity(this.opacityValue)
.translate({ x: this.translateX })
.animation({ curve: curves.springMotion() })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
自定义属性动画
ArkUI提供@AnimatableExtend装饰器,用于自定义可动画属性接口。由于参数的数据类型必须具备一定程度的连续性,自定义可动画属性接口的参数类型仅支持number类型和实现AnimatableArithmetic接口的自定义类型。通过自定义可动画属性接口和可动画数据类型,在使用animateTo或animation执行动画时,通过逐帧回调函数修改不可动画属性接口的值,能够让不可动画属性接口实现动画效果。也可通过逐帧回调函数每帧修改可动画属性的值,实现逐帧布局的效果。
实现案例:
// 第一步:使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(Text)
function animatableWidth(width: number) {
.width(width)// 调用系统属性接口,逐帧回调函数每帧修改可动画属性的值,实现逐帧布局的效果。
}
@Entry
@Component
struct AnimatablePropertyExample {
@State textWidth: number = 80;
build() {
Column() {
Text("AnimatableProperty")
.animatableWidth(this.textWidth)// 第二步:将自定义可动画属性接口设置到组件上
.animation({ duration: 2000, curve: Curve.Ease })// 第三步:为自定义可动画属性接口绑定动画
Button("Play")
.onClick(() => {
this.textWidth = this.textWidth == 80 ? 160 : 80;// 第四步:改变自定义可动画属性的参数,产生动画
})
}.width("100%")
.padding(10)
}
}
结束语
鸿蒙应用开发中的属性动画实践是一个复杂而有趣的过程。通过深入理解属性动画的基本概念、组件、实现方法和自定义方式等内容,我们可以更加灵活地运用属性动画来提升应用的视觉效果和交互体验。在未来的鸿蒙应用开发中,相信会有越来越多的开发者利用属性动画等技术来创造出更加创新、丰富和引人入胜的应用。
更多推荐
所有评论(0)