AnimatedWidget与AnimatedBuilder:Flutter在鸿蒙平台复用动画逻辑
2026/7/23 4:22:54 网站建设 项目流程


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

概述

在Flutter动画开发中,AnimatedWidgetAnimatedBuilder是两种重要的动画组件复用方式。它们都能够帮助开发者将动画逻辑与UI代码分离,提高代码的复用性和可维护性。

AnimatedWidget核心概念

什么是AnimatedWidget

AnimatedWidget是一个抽象类,它继承自StatefulWidget,用于封装动画逻辑。通过继承AnimatedWidget,可以将动画相关的代码抽取到一个独立的组件中,实现动画逻辑的复用。

创建AnimatedWidget

classFadeWidgetextendsAnimatedWidget{constFadeWidget({super.key,requiredAnimation<double>animation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animation<double>get_animation=>listenableasAnimation<double>;@overrideWidgetbuild(BuildContextcontext){returnOpacity(opacity:_animation.value,child:child,);}}

AnimatedWidget的使用

classAnimatedWidgetExampleextendsStatefulWidget{constAnimatedWidgetExample({super.key});@overrideState<AnimatedWidgetExample>createState()=>_AnimatedWidgetExampleState();}class_AnimatedWidgetExampleStateextendsState<AnimatedWidgetExample>withSingleTickerProviderStateMixin{lateAnimationController_controller;@overridevoidinitState(){super.initState();_controller=AnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.repeat(reverse:true);}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('AnimatedWidget示例')),body:Center(child:FadeWidget(animation:_controller,child:constFlutterLogo(size:200),),),);}}

AnimatedBuilder核心概念

什么是AnimatedBuilder

AnimatedBuilder是一个便捷的动画构建器,它接收一个builder回调函数,在动画值变化时重新构建UI。AnimatedBuilder不需要创建新类,可以直接在代码中使用。

创建AnimatedBuilder

AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:0.5+_controller.value*0.5,child:child,);},child:constFlutterLogo(size:200),)

AnimatedBuilder的使用

classAnimatedBuilderExampleextendsStatefulWidget{constAnimatedBuilderExample({super.key});@overrideState<AnimatedBuilderExample>createState()=>_AnimatedBuilderExampleState();}class_AnimatedBuilderExampleStateextendsState<AnimatedBuilderExample>withSingleTickerProviderStateMixin{lateAnimationController_controller;@overridevoidinitState(){super.initState();_controller=AnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.repeat(reverse:true);}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('AnimatedBuilder示例')),body:Center(child:AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:0.5+_controller.value*0.5,child:child,);},child:constFlutterLogo(size:200),),),);}}

AnimatedWidget与AnimatedBuilder对比

特性AnimatedWidgetAnimatedBuilder
创建方式需要创建新类直接使用builder回调
复用性高,适合通用动画组件低,适合一次性使用
代码量较多较少
适用场景通用动画组件封装临时动画效果
性能需要创建新组件实例直接回调,更轻量
灵活性固定的动画逻辑灵活的动画逻辑

使用AnimatedBuilder优化性能

传递child参数

将不变的子Widget传递给child参数,可以避免不必要的重建:

AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:_scaleAnimation.value,child:child,);},child:constFlutterLogo(size:100),)

组合多个动画

AnimatedBuilder可以方便地组合多个动画:

AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.translate(offset:Offset(_slideAnimation.value,0),child:Opacity(opacity:_fadeAnimation.value,child:child,),);},child:constFlutterLogo(size:100),)

使用AnimatedWidget封装通用组件

封装淡入动画组件

classFadeInAnimationextendsAnimatedWidget{constFadeInAnimation({super.key,requiredAnimation<double>animation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animation<double>get_animation=>listenableasAnimation<double>;@overrideWidgetbuild(BuildContextcontext){returnOpacity(opacity:_animation.value,child:child,);}}

封装缩放动画组件

classScaleAnimationextendsAnimatedWidget{constScaleAnimation({super.key,requiredAnimation<double>animation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animation<double>get_animation=>listenableasAnimation<double>;@overrideWidgetbuild(BuildContextcontext){returnTransform.scale(scale:_animation.value,child:child,);}}

复杂动画场景

组合AnimatedWidget

classComplexAnimationextendsStatefulWidget{constComplexAnimation({super.key});@overrideState<ComplexAnimation>createState()=>_ComplexAnimationState();}class_ComplexAnimationStateextendsState<ComplexAnimation>withSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimation<double>_fadeAnimation;lateAnimation<double>_scaleAnimation;@overridevoidinitState(){super.initState();_controller=AnimationController(duration:constDuration(seconds:2),vsync:this,);_fadeAnimation=CurvedAnimation(parent:_controller,curve:Curves.easeInOut);_scaleAnimation=Tween<double>(begin:0.5,end:1).animate(CurvedAnimation(parent:_controller,curve:Curves.easeOut),);_controller.repeat(reverse:true);}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('复杂动画组合')),body:Center(child:FadeInAnimation(animation:_fadeAnimation,child:ScaleAnimation(animation:_scaleAnimation,child:constFlutterLogo(size:200),),),),);}}

使用AnimatedBuilder实现复杂动画

classComplexAnimatedBuilderextendsStatefulWidget{constComplexAnimatedBuilder({super.key});@overrideState<ComplexAnimatedBuilder>createState()=>_ComplexAnimatedBuilderState();}class_ComplexAnimatedBuilderStateextendsState<ComplexAnimatedBuilder>withSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimation<double>_rotationAnimation;lateAnimation<double>_scaleAnimation;@overridevoidinitState(){super.initState();_controller=AnimationController(duration:constDuration(seconds:3),vsync:this,);_rotationAnimation=Tween<double>(begin:0,end:2*pi).animate(CurvedAnimation(parent:_controller,curve:Curves.linear),);_scaleAnimation=Tween<double>(begin:0.5,end:1.5).animate(CurvedAnimation(parent:_controller,curve:Curves.easeInOut),);_controller.repeat();}@overridevoiddispose(){_controller.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('复杂AnimatedBuilder')),body:Center(child:AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.rotate(angle:_rotationAnimation.value,child:Transform.scale(scale:_scaleAnimation.value,child:child,),);},child:constFlutterLogo(size:200),),),);}}

性能优化最佳实践

使用AnimatedBuilder避免重建

// 不推荐:每次动画都会重建FlutterLogoAnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:_controller.value,child:constFlutterLogo(size:100),);},)// 推荐:FlutterLogo只创建一次AnimatedBuilder(animation:_controller,builder:(context,child){returnTransform.scale(scale:_controller.value,child:child,);},child:constFlutterLogo(size:100),)

使用RepaintBoundary隔离重绘

AnimatedBuilder(animation:_controller,builder:(context,child){returnRepaintBoundary(child:Transform.scale(scale:_controller.value,child:child,),);},child:constFlutterLogo(size:100),)

鸿蒙平台注意事项

在鸿蒙平台使用AnimatedWidgetAnimatedBuilder时,需要注意以下几点:

  1. 组件创建开销AnimatedWidget每次创建都会产生组件实例开销,对于简单动画优先使用AnimatedBuilder
  2. 性能测试:在鸿蒙真机上测试复杂动画的流畅度
  3. 资源释放:确保AnimationControllerdispose方法中正确释放
  4. 动画复杂度:避免在动画回调中进行大量计算

总结

AnimatedWidgetAnimatedBuilder是Flutter动画系统中两种重要的复用方式。AnimatedWidget适合封装通用的动画组件,具有较高的复用性;AnimatedBuilder适合快速实现临时动画效果,更加轻量灵活。在实际开发中,应根据具体场景选择合适的方式,并注意性能优化,确保动画在鸿蒙平台上流畅运行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询