HarmonyOS 动画体系实战animateTo 显式动画、属性动画与页面转场前言动画是鸿蒙应用“高级感”的来源但很多开发者分不清animateTo、属性动画animation、显式动画animateTo/animateTo的变体以及页面转场pageTransition的边界导致写了大量重复代码、动画不生效或卡顿。本文从“谁触发动画”这一核心视角把鸿蒙的三套动画能力讲透并给出可运行的对照示例。问题描述常见困惑集中在以下几点修改了状态变量组件却“瞬间”跳变没有过渡动画。在onClick里直接改this.width动画时灵时不灵。列表项删除/插入没有过渡体验生硬。页面跳转时没有转场想知道怎么统一配置进出场动画。这些问题的根因是只有“被动画作用域包裹的属性变化”才会产生过渡而不同 API 的作用域与触发时机完全不同。细节解析鸿蒙动画按“触发方式”分为两类属性动画隐式动画给组件本身加.animation({...})之后该组件上被监听的属性宽高、位置、透明度、背景色等发生变化时自动补间。适合“单个组件自身变化”。显式动画animateTo把一段“会修改状态的闭包”包进去闭包内所有被监听属性的变化都会以同一个动画参数过渡。适合“多个组件、多处状态联动变化”。两者关键差异维度属性动画.animation()显式动画animateTo作用对象当前组件自身属性闭包内所有变化触发属性变化自动触发手动调用闭包多组件联动需每个组件各自声明一次声明覆盖全部典型场景按钮缩放、颜色渐变布局整体切换、列表重排页面转场则独立于组件动画通过pageTransition()在Entry页面配置作用于路由跳转的进出场。另外要注意width/height用number配合动画才平滑字符串如100%无法补间。状态必须用State等可观察装饰器普通let变量变化不会触发 UI 重绘自然也没有动画。示例代码// Index.etsEntryComponentstruct AnimationDemo{StateboxWidth:number100StateboxColor:string#317affStateisBig:booleanfalseStateopacity:number1// 页面转场统一配置淡入淡出 滑动pageTransition(){PageTransitionEnter({type:RouteType.Push,duration:300}).slide(SlideEffect.Right).opacity(0)PageTransitionExit({type:RouteType.Push,duration:300}).slide(SlideEffect.Left).opacity(0)}build(){Column({space:20}){// 1) 属性动画隐式组件自身属性变化自动补间Text(属性动画点我缩放).fontSize(16).onClick((){this.isBig!this.isBig}).scale({x:this.isBig?1.4:1,y:this.isBig?1.4:1}).animation({duration:300,curve:Curve.EaseInOut})// 2) 显式动画闭包内所有变化统一过渡Button(显式动画宽高颜色一起变).width(this.boxWidth).height(this.boxWidth).backgroundColor(this.boxColor).opacity(this.opacity).onClick((){animateTo({duration:400,curve:Curve.Spring},(){this.boxWidththis.boxWidth100?200:100this.boxColorthis.boxColor#317aff?#ff7a45:#317affthis.opacitythis.opacity1?0.4:1})})// 3) 列表插入/删除的过渡配合 ForEach 动画作用域Button(加一条).onClick((){animateTo({duration:300},(){this.items.push(item-${this.items.length})})})}.width(100%).height(100%).padding(20)}Stateitems:string[][item-0,item-1]}要点说明.animation()紧跟在会变化的属性之后声明即可框架会在该属性下一次变化时自动补间。animateTo的闭包里直接给State赋值即可不要包在setTimeout或异步里否则会脱离动画作用域。若希望“入场就有动画”可在aboutToAppear里用animateTo从初始值过渡到目标值。总结组件自身变化 → 用.animation()隐式、简单。多处状态联动 → 用animateTo显式、统一。路由跳转过渡 → 在Entry页面用pageTransition()。动画属性必须是可补间的数值/颜色/透明度且状态必须用State等可观察装饰器。善用Curve.Spring等曲线让动画更自然避免生硬的线性位移。掌握这三者的分工就能用最少的代码覆盖 90% 的动效需求同时避免“动画不生效”的经典坑。