news 2026/7/21 15:25:02

AnimationController动画基础_Flutter在鸿蒙平台实现流畅UI动画

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AnimationController动画基础_Flutter在鸿蒙平台实现流畅UI动画




作者:付文龙(红目香薰)
仓库地址:https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git
联系邮箱:372699828@qq.com

概述

Flutter动画系统是一个强大的动画框架,它基于AnimationAnimationController实现流畅的UI动画效果。Flutter动画系统的核心特点:

  • 声明式动画:通过状态驱动动画,无需手动管理帧更新
  • 高性能:基于GPU渲染,60fps流畅动画
  • 灵活:支持各种动画类型和曲线
  • 组合性:可以组合多个动画实现复杂效果

动画的重要性

  1. 用户体验提升:动画使界面更加生动和流畅
  2. 交互反馈:提供视觉反馈,增强用户操作感知
  3. 引导用户:通过动画引导用户注意力
  4. 品牌个性:独特的动画风格可以体现品牌特色

核心概念

Animation

Animation是Flutter动画的核心抽象类,它代表一个随时间变化的值。动画的值可以是任意类型:double、Color、Offset等。

AnimationController

AnimationControllerAnimation的子类,用于控制动画的播放、暂停、反向、重复等操作。

Tween

Tween用于定义数值的插值范围,将动画的进度值(0-1)映射到实际的数值范围。

CurvedAnimation

CurvedAnimation用于添加曲线效果,使动画更加自然。

AnimatedBuilder

AnimatedBuilder是一个Widget,用于监听动画变化并重建UI。

实现步骤

第一步:创建AnimationController

首先创建一个AnimationController,需要指定vsyncduration

classAnimationDemoextendsStatefulWidget{constAnimationDemo({super.key});@overrideState<AnimationDemo>createState()=>_AnimationDemoState();}class_AnimationDemoStateextendsState<AnimationDemo>withSingleTickerProviderStateMixin{lateAnimationController_controller;@overridevoidinitState(){super.initState();_controller=AnimationController(vsync:this,duration:constDuration(seconds:2),);}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnScaffold(body:Center(child:AnimatedBuilder(animation:_controller,builder:(context,child){returnContainer(width:_controller.value*300,height:_controller.value*300,color:Colors.blue,);},),),floatingActionButton:FloatingActionButton(onPressed:()=>_controller.forward(),child:constIcon(Icons.play_arrow),),);}}

第二步:使用Tween插值

使用Tween定义数值的插值范围。

// 数值插值Animation<double>sizeAnimation=Tween<double>(begin:0,end:300).animate(_controller);// 颜色插值Animation<Color>colorAnimation=ColorTween(begin:Colors.blue,end:Colors.red,).animate(_controller);// 边框插值Animation<BorderRadius>borderRadiusAnimation=BorderRadiusTween(begin:BorderRadius.circular(0),end:BorderRadius.circular(50),).animate(_controller);// 位置插值Animation<Offset>offsetAnimation=Tween<Offset>(begin:constOffset(0,0),end:constOffset(100,100),).animate(_controller);

第三步:使用CurvedAnimation

使用CurvedAnimation添加曲线效果。

Animation<double>curvedAnimation=CurvedAnimation(parent:_controller,curve:Curves.easeInOut,);Animation<double>sizeAnimation=Tween<double>(begin:0,end:300).animate(curvedAnimation);

第四步:在AnimatedBuilder中使用动画

AnimatedBuilder(animation:_animation,builder:(context,child){returnContainer(width:_animation.value,height:_animation.value,color:Colors.blue,);},)

AnimationController方法

基本控制方法

_controller.forward();// 正向播放(从0到1)_controller.reverse();// 反向播放(从1到0)_controller.reset();// 重置到初始状态(值为0)_controller.repeat();// 重复播放_controller.stop();// 停止播放_controller.animateTo(0.5);// 动画到指定值(0-1)_controller.animateBack(0.5);// 反向动画到指定值

属性设置

_controller.duration=constDuration(seconds:1);// 设置动画时长_controller.reverseDuration=constDuration(seconds:1);// 设置反向时长_controller.value=0.5;// 设置当前值_controller.lowerBound=0;// 设置下限_controller.upperBound=1;// 设置上限_controller.isAnimating;// 是否正在播放_controller.status;// 当前状态

动画状态

AnimationStatus.dismissed;// 动画在起始位置(值为0)AnimationStatus.forward;// 动画正向播放中AnimationStatus.reverse;// 动画反向播放中AnimationStatus.completed;// 动画在结束位置(值为1)

监听动画

监听值变化

_controller.addListener((){setState((){});});

监听状态变化

_controller.addStatusListener((status){if(status==AnimationStatus.completed){_controller.reverse();}elseif(status==AnimationStatus.dismissed){_controller.forward();}});

常用曲线

Flutter提供了多种内置曲线,使动画更加自然。

曲线名称效果适用场景
Curves.linear线性变化匀速动画
Curves.ease缓入开始缓慢,然后加速
Curves.easeIn缓入开始缓慢
Curves.easeOut缓出结束缓慢
Curves.easeInOut缓入缓出开始和结束都缓慢
Curves.bounceIn弹跳进入弹跳效果
Curves.bounceOut弹跳退出弹跳效果
Curves.elasticIn弹性进入弹性效果
Curves.elasticOut弹性退出弹性效果
Curves.fastOutSlowIn快速开始,缓慢结束Material Design标准

组合动画

多个动画同步

classComboAnimationextendsStatefulWidget{constComboAnimation({super.key});@overrideState<ComboAnimation>createState()=>_ComboAnimationState();}class_ComboAnimationStateextendsState<ComboAnimation>withSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimation<double>_sizeAnimation;lateAnimation<Color>_colorAnimation;lateAnimation<double>_opacityAnimation;@overridevoidinitState(){super.initState();_controller=AnimationController(vsync:this,duration:constDuration(seconds:2),);_sizeAnimation=Tween<double>(begin:50,end:200).animate(_controller);_colorAnimation=ColorTween(begin:Colors.blue,end:Colors.red).animate(_controller);_opacityAnimation=Tween<double>(begin:0.3,end:1).animate(_controller);_controller.repeat(reverse:true);}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnAnimatedBuilder(animation:_controller,builder:(context,child){returnOpacity(opacity:_opacityAnimation.value,child:Container(width:_sizeAnimation.value,height:_sizeAnimation.value,color:_colorAnimation.value,borderRadius:BorderRadius.circular(_sizeAnimation.value/4),),);},);}}

动画延迟

Animation<double>delayedAnimation=Tween<double>(begin:0,end:100).animate(CurvedAnimation(parent:_controller,curve:constInterval(0.5,1.0),),);

动画性能优化

使用AnimatedBuilder

AnimatedBuilder只会重建builder中的内容,不会重建整个Widget树。

AnimatedBuilder(animation:_animation,builder:(context,child){returnContainer(width:_animation.value,height:_animation.value,child:child,);},child:constText('Hello'),)

使用AnimatedWidget

AnimatedWidget是一个抽象类,可以继承它创建自定义动画Widget。

classAnimatedContainerextendsAnimatedWidget{constAnimatedContainer({super.key,requiredAnimation<double>animation,}):super(listenable:animation);@overrideWidgetbuild(BuildContextcontext){finalanimation=listenableasAnimation<double>;returnContainer(width:animation.value,height:animation.value,color:Colors.blue,);}}

使用AnimatedOpacity、AnimatedContainer等

Flutter提供了许多预定义的动画Widget。

AnimatedOpacity(opacity:_opacity,duration:constDuration(seconds:1),child:constText('Hello'),)AnimatedContainer(width:_width,height:_height,color:_color,duration:constDuration(seconds:1),)AnimatedPositioned(left:_left,top:_top,duration:constDuration(seconds:1),child:constText('Hello'),)

Hero动画

Hero动画用于页面间的共享元素过渡。

// 源页面Hero(tag:'image',child:Image.network('https://example.com/image.jpg'),)// 目标页面Hero(tag:'image',child:Image.network('https://example.com/image.jpg'),)

自定义曲线

创建自定义曲线

classCustomCurveextendsCurve{@overridedoubletransform(double t){returnt*t;}}Animation<double>customAnimation=CurvedAnimation(parent:_controller,curve:CustomCurve(),);

使用曲线组合

Animation<double>combinedAnimation=CurvedAnimation(parent:_controller,curve:Curves.easeIn.flipped,);

完整示例

弹跳按钮动画

import'package:flutter/material.dart';voidmain(){runApp(constMaterialApp(home:BounceButtonDemo()));}classBounceButtonDemoextendsStatefulWidget{constBounceButtonDemo({super.key});@overrideState<BounceButtonDemo>createState()=>_BounceButtonDemoState();}class_BounceButtonDemoStateextendsState<BounceButtonDemo>withSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimation<double>_scaleAnimation;lateAnimation<double>_opacityAnimation;@overridevoidinitState(){super.initState();_controller=AnimationController(vsync:this,duration:constDuration(milliseconds:500),);_scaleAnimation=Tween<double>(begin:1,end:0.8).animate(CurvedAnimation(parent:_controller,curve:Curves.bounceIn,),);_opacityAnimation=Tween<double>(begin:1,end:0.5).animate(_controller);}@overridevoiddispose(){_controller.dispose();super.dispose();}void_onPressed(){_controller.forward().then((_){_controller.reverse();});}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText("弹跳按钮动画")),body:Center(child:AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:_scaleAnimation.value,child:Opacity(opacity:_opacityAnimation.value,child:ElevatedButton(onPressed:_onPressed,style:ElevatedButton.styleFrom(padding:constEdgeInsets.symmetric(horizontal:40,vertical:16),textStyle:constTextStyle(fontSize:20),),child:constText("点击弹跳"),),),);},),),);}}

最佳实践

1. 使用SingleTickerProviderStateMixin

SingleTickerProviderStateMixin提供vsync,确保动画在Widget可见时才运行。

class_MyWidgetStateextendsState<MyWidget>withSingleTickerProviderStateMixin{lateAnimationController_controller;}

2. 在dispose中释放资源

@overridevoiddispose(){_controller.dispose();super.dispose();}

3. 使用AnimatedBuilder避免不必要的重建

AnimatedBuilder(animation:_animation,builder:(context,child){returnContainer(width:_animation.value);},child:constText('不变的内容'),)

4. 优先使用预定义的动画Widget

AnimatedOpacity(...)AnimatedContainer(...)AnimatedPositioned(...)

5. 使用曲线使动画更自然

CurvedAnimation(parent:_controller,curve:Curves.easeInOut,)

6. 组合多个动画时使用同一个Controller

_sizeAnimation=Tween(begin:50,end:200).animate(_controller);_colorAnimation=ColorTween(begin:Colors.blue,end:Colors.red).animate(_controller);

总结

Flutter动画系统是一个强大而灵活的动画框架,通过AnimationControllerTweenCurvedAnimationAnimatedBuilder等组件,可以实现各种复杂的动画效果。

核心要点:

  • 使用AnimationController控制动画的播放、暂停、反向等
  • 使用Tween定义数值的插值范围
  • 使用CurvedAnimation添加曲线效果
  • 使用AnimatedBuilder监听动画变化并重建UI
  • dispose中释放AnimationController资源

通过合理使用Flutter动画系统,可以创建出流畅、自然的用户界面,提升用户体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/21 15:24:29

2026程序员AI实战:从玩具到真实项目落地,提升职场竞争力的秘诀

本文以作者真实商业项目为例&#xff0c;展示了AI在程序员工作中的最新落地应用。AI能深度融入企业真实项目&#xff0c;帮助程序员看懂项目源码、迭代接口、改bug、生成文档等&#xff0c;显著提升工作效率。文章强调AI不是装逼工具&#xff0c;而是真正的生产力工具&#xff…

作者头像 李华
网站建设 2026/7/21 15:23:26

终极指南:使用ipatool跨平台下载iOS应用包

终极指南&#xff1a;使用ipatool跨平台下载iOS应用包 【免费下载链接】ipatool Command-line tool that allows searching and downloading app packages (known as ipa files) from the iOS App Store 项目地址: https://gitcode.com/GitHub_Trending/ip/ipatool 你是…

作者头像 李华
网站建设 2026/7/21 15:23:04

Java代码审计:常见漏洞与安全开发实践

1. Java代码审计概述&#xff1a;为什么需要关注不安全代码&#xff1f; 在Java开发领域&#xff0c;代码审计正逐渐成为保障应用安全的关键环节。去年某知名电商平台的数据泄露事件&#xff0c;根源就是一段未经验证的SQL拼接代码。这类安全问题往往隐藏在看似正常的业务逻辑中…

作者头像 李华
网站建设 2026/7/21 15:18:18

轻松解锁旧款Mac潜能:OpenCore Legacy Patcher完全使用指南

轻松解锁旧款Mac潜能&#xff1a;OpenCore Legacy Patcher完全使用指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 还在为苹果官方不支持的老款Mac无法升…

作者头像 李华
网站建设 2026/7/21 15:17:01

UE5 C++编译失败:VS升级后三大常见问题与解决方案

1. 项目概述&#xff1a;当UE5遇上VS升级&#xff0c;C编译为何“罢工”&#xff1f; 如果你是一名UE5的C开发者&#xff0c;最近心血来潮把Visual Studio&#xff08;VS&#xff09;升级到了最新版&#xff0c;满心欢喜地打开项目准备大干一场&#xff0c;结果等待你的却是满屏…

作者头像 李华
网站建设 2026/7/21 15:14:49

SpringBoot3+Poi-tl实现高效Word文档动态生成

1. 项目概述最近在开发一个企业级报表系统时&#xff0c;遇到了一个典型需求&#xff1a;需要根据业务数据动态生成格式规范的Word文档&#xff0c;并提供给用户下载。这种场景在OA系统、合同管理系统、报表导出等业务中非常常见。经过技术选型&#xff0c;我最终选择了SpringB…

作者头像 李华