作者付文龙红目香薰仓库地址https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git联系邮箱372699828qq.com概述在Flutter动画系统中监听动画的状态变化和值变化是实现复杂交互的关键。通过addListener和addStatusListener可以在动画执行过程中执行自定义逻辑实现更加灵活的动画控制。动画监听核心概念为什么需要监听在实际开发中我们经常需要在动画开始时执行初始化操作在动画结束时执行清理或跳转逻辑在动画过程中实时更新UI或数据根据动画状态执行不同的业务逻辑动画状态说明状态说明dismissed动画在起点lowerBoundforward动画正向播放中reverse动画反向播放中completed动画在终点upperBoundaddListener值监听基本用法addListener用于监听动画值的变化在每一帧都会被调用_controller.addListener((){print(当前值:${_controller.value});});值监听实际应用classValueListenerExampleextendsStatefulWidget{constValueListenerExample({super.key});overrideStateValueListenerExamplecreateState()_ValueListenerExampleState();}class_ValueListenerExampleStateextendsStateValueListenerExamplewithSingleTickerProviderStateMixin{lateAnimationController_controller;double _currentValue0;overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.addListener((){setState((){_currentValue_controller.value;});});}overridevoiddispose(){_controller.dispose();super.dispose();}overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText(值监听示例)),body:Column(children:[Text(当前值:${_currentValue.toStringAsFixed(2)}),constSizedBox(height:20),Container(width:200,height:20,color:Colors.grey[300],child:Container(width:_currentValue*200,height:20,color:Colors.blue,),),constSizedBox(height:20),ElevatedButton(onPressed:()_controller.forward(from:0),child:constText(播放动画),),],),);}}移除值监听void_listener(){setState((){_currentValue_controller.value;});}overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.addListener(_listener);}overridevoiddispose(){_controller.removeListener(_listener);_controller.dispose();super.dispose();}addStatusListener状态监听基本用法addStatusListener用于监听动画状态的变化_controller.addStatusListener((status){switch(status){caseAnimationStatus.dismissed:print(动画在起点);break;caseAnimationStatus.forward:print(正向播放中);break;caseAnimationStatus.reverse:print(反向播放中);break;caseAnimationStatus.completed:print(动画在终点);break;}});状态监听实际应用classStatusListenerExampleextendsStatefulWidget{constStatusListenerExample({super.key});overrideStateStatusListenerExamplecreateState()_StatusListenerExampleState();}class_StatusListenerExampleStateextendsStateStatusListenerExamplewithSingleTickerProviderStateMixin{lateAnimationController_controller;String_statusdismissed;overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.addStatusListener((status){setState((){_statusstatus.toString().split(.)[1];});});}overridevoiddispose(){_controller.dispose();super.dispose();}overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText(状态监听示例)),body:Column(children:[Text(当前状态:$_status),constSizedBox(height:20),FadeTransition(opacity:_controller,child:constFlutterLogo(size:200),),constSizedBox(height:20),Row(mainAxisAlignment:MainAxisAlignment.center,children:[ElevatedButton(onPressed:_controller.forward,child:constText(正向)),constSizedBox(width:8),ElevatedButton(onPressed:_controller.reverse,child:constText(反向)),constSizedBox(width:8),ElevatedButton(onPressed:_controller.reset,child:constText(重置)),],),],),);}}移除状态监听void_statusListener(AnimationStatusstatus){setState((){_statusstatus.toString().split(.)[1];});}overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.addStatusListener(_statusListener);}overridevoiddispose(){_controller.removeStatusListener(_statusListener);_controller.dispose();super.dispose();}动画完成回调使用whenCompletewhenComplete是一个便捷的方法在动画完成时执行回调_controller.forward().whenComplete((){print(动画完成);Navigator.push(context,MaterialPageRoute(builder:(context)constNextPage()));});使用addStatusListener监听completed状态_controller.addStatusListener((status){if(statusAnimationStatus.completed){print(动画完成);Navigator.push(context,MaterialPageRoute(builder:(context)constNextPage()));}});组合监听同时监听值和状态classCombinedListenerExampleextendsStatefulWidget{constCombinedListenerExample({super.key});overrideStateCombinedListenerExamplecreateState()_CombinedListenerExampleState();}class_CombinedListenerExampleStateextendsStateCombinedListenerExamplewithSingleTickerProviderStateMixin{lateAnimationController_controller;String_statusdismissed;double _value0;overridevoidinitState(){super.initState();_controllerAnimationController(duration:constDuration(seconds:2),vsync:this,);_controller.addListener((){setState((){_value_controller.value;});});_controller.addStatusListener((status){setState((){_statusstatus.toString().split(.)[1];});});}overridevoiddispose(){_controller.dispose();super.dispose();}overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText(组合监听示例)),body:Column(children:[Text(状态:$_status, 值:${_value.toStringAsFixed(2)}),constSizedBox(height:20),FadeTransition(opacity:_controller,child:constFlutterLogo(size:200),),constSizedBox(height:20),ElevatedButton(onPressed:()_controller.forward(from:0),child:constText(播放动画),),],),);}}监听在实际场景中的应用场景1登录动画void_handleLogin(){_controller.forward().whenComplete((){Navigator.pushReplacement(context,MaterialPageRoute(builder:(context)constHomePage()),);});}场景2进度动画_controller.addListener((){setState((){_progress_controller.value*100;});});_controller.addStatusListener((status){if(statusAnimationStatus.completed){setState((){_isCompletetrue;});}});场景3链式动画_controller.addStatusListener((status){if(statusAnimationStatus.completed){_secondController.forward();}});监听性能优化避免在监听器中进行复杂计算// 不推荐_controller.addListener((){// 复杂计算_result_complexCalculation(_controller.value);setState((){});});// 推荐将计算移到动画外部使用AnimatedBuilder代替addListener对于UI更新优先使用AnimatedBuilder// 不推荐_controller.addListener((){setState((){});});overrideWidgetbuild(BuildContextcontext){returnOpacity(opacity:_controller.value,child:constFlutterLogo(size:100),);}// 推荐AnimatedBuilder(animation:_controller,builder:(context,child){returnOpacity(opacity:_controller.value,child:child,);},child:constFlutterLogo(size:100),)鸿蒙平台注意事项在鸿蒙平台使用动画监听时需要注意以下几点及时移除监听器在dispose方法中移除所有监听器防止内存泄漏避免内存泄漏确保监听器中没有持有对State的强引用性能测试在鸿蒙真机上测试监听回调的执行效率线程安全确保监听器中的操作是线程安全的总结动画监听是Flutter动画系统中实现复杂交互的关键机制。通过addListener监听值变化和addStatusListener监听状态变化可以在动画执行过程中执行自定义逻辑。在实际应用中动画监听常用于登录跳转、进度更新、链式动画等场景。掌握动画监听的使用方式能够为应用增添更加丰富的交互体验。