鸿蒙开发-UI-组件2
鸿蒙开发-UI-组件3
鸿蒙开发-UI-气泡/菜单
鸿蒙开发-UI-页面路由
鸿蒙开发-UI-组件导航-Navigation
鸿蒙开发-UI-组件导航-Tabs
鸿蒙开发-UI-图形-图片
鸿蒙开发-UI-图形-绘制几何图形
鸿蒙开发-UI-图形-绘制自定义图形
文章目录
前言
一、概述
二、页面内动画
1.布局更新动画
1.1 使用显示动画产生布局更新动画
1.2 使用属性动画产生布局更新动画
总结
前言
上文详细学习了鸿蒙开发UI使用画布绘制自定义图形的相关知识,了解画布绘制的三种方式,同时学习了画布组件的常用用法,以及如何绘制规则、不规则图形、图片图像等,本文将学习鸿蒙开发UI动画
一、概述
动画的原理:一个时间段内,多次改变UI外观,由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画。UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率FPS(Frame Per Second),即每秒的动画帧数,帧率越高则动画就会越流畅。
ArkUI动画:改变属性值+指定动画参数(动画时长、变化规律(即曲线)等参数)。当属性值发生变化后,按照动画参数,从原来的状态过渡到新的状态,即形成一个动画。
ArkUI提供的动画能力按照页面的分类方式,可分为页面内的动画和页面间的动画。
按照基础能力分,可分为属性动画、显式动画、转场动画三部分
二、页面内动画
1.布局更新动画
1.1 使用显示动画产生布局更新动画
显示动画接口
//第一个参数指定动画参数,第二个参数为动画的闭包函数。
animateTo(value: AnimateParam, event: () => void): void
代码示例:当Column组件的alignItems属性改变后,其子组件的布局位置结果发生变化,只要属性是在animateTo的闭包函数中修改的,那么由其引起的所有变化都会按照animateTo的动画参数执行动画过渡到终点值。
@Entry
@Component
struct LayoutChange {
//step1:定义用于控制Column的alignItems属性
@State itemAlign: HorizontalAlign = HorizontalAlign.Start;
allAlign: HorizontalAlign[] = [HorizontalAlign.Start, HorizontalAlign.Center, HorizontalAlign.End];
alignIndex: number = 0;
build() {
Column() {
Column({ space: 10 }) {
Button("1").width(100).height(50)
Button("2").width(100).height(50)
Button("3").width(100).height(50)
}
.margin(20)
.alignItems(this.itemAlign)
.borderWidth(2)
.width("90%")
.height(200)
Button("click").onClick(() => {
//step2:设置动画参数:时长为1000ms,曲线为EaseInOut
animateTo({ duration: 1000, curve: Curve.EaseInOut }, () => {
this.alignIndex = (this.alignIndex + 1) % this.allAlign.length;
//step3:改变属性:在闭包函数中修改this.itemAlign参数,使Column容器内部孩子的布局方式变化,使用动画过渡到新位置
this.itemAlign = this.allAlign[this.alignIndex];
});
})
}
.width("100%")
.height("100%")
}
}
除了直接改变布局方式外,也可直接修改组件的宽、高、位置,来实现动画效果
1.2 使用属性动画产生布局更新动画
显式动画把要执行动画的属性的修改放在闭包函数中触发动画,而属性动画则无需使用闭包,把animation属性加在要做属性动画的组件的属性后即可。
属性动画接口
//参数指定动画参数。
animation(value: AnimateParam)
代码示例,在animation属性之前的属性值发生变更,组件才会产生动画效果,在animation属性之后添加的属性变化,组件不会有动画效果。
@Entry
@Component
struct LayoutChange2 {
@State myWidth: number = 100;
@State myHeight: number = 50;
@State flag: boolean = false;
@State myColor: Color = Color.Blue;
build() {
Column({ space: 10 }) {
Button("text")
.type(ButtonType.Normal)
.width(this.myWidth)
.height(this.myHeight)
//step1: 在type、width、height属性之后添加animation属性,只有type、width、height属性变更,button组件才有指定的动画(时长为1000ms,曲线为Ease)效果
.animation({ duration: 1000, curve: Curve.Ease })
// animation对下面的backgroundColor、margin属性不生效
.backgroundColor(this.myColor)
.margin(20)
Button("area: click me")
.fontSize(12)
.onClick(() => {
//step2: 改变属性值,配置了属性动画的属性会进行动画过渡
if (this.flag) {
this.myWidth = 100;
this.myHeight = 50;
this.myColor = Color.Blue;
} else {
this.myWidth = 200;
this.myHeight = 100;
this.myColor = Color.Pink;
}
this.flag = !this.flag;
})
}
}
}
注:
1. 属性动画会按照指定的属性动画参数执行动画。每个组件可为自己的属性配置不同参数的属性动画。
2. 显式动画会对动画闭包前后造成的所有界面差异执行动画,且使用同一动画参数,适用于统一执行的场景。显式动画也可以用于一些非属性变量造成的动画,如if/else的条件,ForEach使用的数组元素的删减。
3. 如果一个属性配置了属性动画,且在显式动画闭包中改变该属性值,属性动画优先生效,会使用属性动画的动画参数。
总结
本文细学习了鸿蒙开发UI使用动画相关知识,了解动画的两个维度的分类方式,详细学习了页面内动画-布局更新动画,下文将学习组件内转场动画。