AnimatedWidget与AnimatedBuilder:Flutter在鸿蒙平台复用动画逻辑 作者付文龙红目香薰仓库地址https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git联系邮箱372699828qq.com概述在Flutter动画开发中AnimatedWidget和AnimatedBuilder是两种重要的动画组件复用方式。它们都能够帮助开发者将动画逻辑与UI代码分离提高代码的复用性和可维护性。AnimatedWidget核心概念什么是AnimatedWidgetAnimatedWidget是一个抽象类它继承自StatefulWidget用于封装动画逻辑。通过继承AnimatedWidget可以将动画相关的代码抽取到一个独立的组件中实现动画逻辑的复用。创建AnimatedWidgetclassFadeWidgetextendsAnimatedWidget{constFadeWidget({super.key,requiredAnimationdoubleanimation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animationdoubleget_animationlistenableasAnimationdouble;overrideWidgetbuild(BuildContextcontext){returnOpacity(opacity:_animation.value,child:child,);}}AnimatedWidget的使用classAnimatedWidgetExampleextendsStatefulWidget{constAnimatedWidgetExample({super.key});overrideStateAnimatedWidgetExamplecreateState()_AnimatedWidgetExampleState();}class_AnimatedWidgetExampleStateextendsStateAnimatedWidgetExamplewithSingleTickerProviderStateMixin{lateAnimationController_controller;overridevoidinitState(){super.initState();_controllerAnimationController(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核心概念什么是AnimatedBuilderAnimatedBuilder是一个便捷的动画构建器它接收一个builder回调函数在动画值变化时重新构建UI。AnimatedBuilder不需要创建新类可以直接在代码中使用。创建AnimatedBuilderAnimatedBuilder(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});overrideStateAnimatedBuilderExamplecreateState()_AnimatedBuilderExampleState();}class_AnimatedBuilderExampleStateextendsStateAnimatedBuilderExamplewithSingleTickerProviderStateMixin{lateAnimationController_controller;overridevoidinitState(){super.initState();_controllerAnimationController(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,requiredAnimationdoubleanimation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animationdoubleget_animationlistenableasAnimationdouble;overrideWidgetbuild(BuildContextcontext){returnOpacity(opacity:_animation.value,child:child,);}}封装缩放动画组件classScaleAnimationextendsAnimatedWidget{constScaleAnimation({super.key,requiredAnimationdoubleanimation,requiredthis.child,}):super(listenable:animation);finalWidgetchild;Animationdoubleget_animationlistenableasAnimationdouble;overrideWidgetbuild(BuildContextcontext){returnTransform.scale(scale:_animation.value,child:child,);}}复杂动画场景组合AnimatedWidgetclassComplexAnimationextendsStatefulWidget{constComplexAnimation({super.key});overrideStateComplexAnimationcreateState()_ComplexAnimationState();}class_ComplexAnimationStateextendsStateComplexAnimationwithSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimationdouble_fadeAnimation;lateAnimationdouble_scaleAnimation;overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_fadeAnimationCurvedAnimation(parent:_controller,curve:Curves.easeInOut);_scaleAnimationTweendouble(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});overrideStateComplexAnimatedBuildercreateState()_ComplexAnimatedBuilderState();}class_ComplexAnimatedBuilderStateextendsStateComplexAnimatedBuilderwithSingleTickerProviderStateMixin{lateAnimationController_controller;lateAnimationdouble_rotationAnimation;lateAnimationdouble_scaleAnimation;overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:3),vsync:this,);_rotationAnimationTweendouble(begin:0,end:2*pi).animate(CurvedAnimation(parent:_controller,curve:Curves.linear),);_scaleAnimationTweendouble(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),)鸿蒙平台注意事项在鸿蒙平台使用AnimatedWidget和AnimatedBuilder时需要注意以下几点组件创建开销AnimatedWidget每次创建都会产生组件实例开销对于简单动画优先使用AnimatedBuilder性能测试在鸿蒙真机上测试复杂动画的流畅度资源释放确保AnimationController在dispose方法中正确释放动画复杂度避免在动画回调中进行大量计算总结AnimatedWidget和AnimatedBuilder是Flutter动画系统中两种重要的复用方式。AnimatedWidget适合封装通用的动画组件具有较高的复用性AnimatedBuilder适合快速实现临时动画效果更加轻量灵活。在实际开发中应根据具体场景选择合适的方式并注意性能优化确保动画在鸿蒙平台上流畅运行。