Flutter中AnimatedWidget动画完成后如何执行指定函数?
嘿,这个问题其实很好解决——咱们只需要监听Animation的状态变化,就能在动画完成时触发自定义函数啦!下面给你两种实用的方案,你可以根据自己的场景来选:
方案一:在父组件中监听动画状态
如果你的动画控制器(AnimationController)是在父组件中创建和管理的,直接给对应的Animation对象添加状态监听就可以了。当动画状态变为AnimationStatus.completed时,执行你的目标函数。
举个完整的例子:
class ParentPage extends StatefulWidget { @override _ParentPageState createState() => _ParentPageState(); } class _ParentPageState extends State<ParentPage> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<Color> _colorAnim; @override void initState() { super.initState(); // 创建动画控制器 _controller = AnimationController( duration: const Duration(seconds: 2), vsync: this, ); // 创建颜色动画 _colorAnim = ColorTween( begin: Colors.lightBlue, end: Colors.deepOrange, ).animate(_controller); // 添加动画状态监听 _colorAnim.addStatusListener((status) { if (status == AnimationStatus.completed) { // 动画完成后执行这里的逻辑 _handleAnimationDone(); } }); // 启动动画 _controller.forward(); } void _handleAnimationDone() { print("颜色动画执行完毕!"); // 这里写你需要执行的自定义逻辑,比如弹窗、跳转页面等 } @override void dispose() { _controller.dispose(); // 记得销毁控制器,防止内存泄漏 super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( // 传入你的自定义AnimatedWidget child: ColorChangeWidget(animation: _colorAnim), ), ); } } // 你的自定义颜色动画组件(继承AnimatedWidget) class ColorChangeWidget extends AnimatedWidget { const ColorChangeWidget({Key? key, required Animation<Color> animation}) : super(key: key, listenable: animation); @override Widget build(BuildContext context) { final anim = listenable as Animation<Color>; return Container( width: 200, height: 200, color: anim.value, ); } }
方案二:把回调封装到自定义组件内部
如果你想让组件更独立,不想让父组件处理监听逻辑,可以把回调函数作为组件参数传入,然后用一个StatefulWidget来包裹你的AnimatedWidget,由State来处理状态监听(因为AnimatedWidget本身是无状态的,没有生命周期方法)。
示例代码:
// 对外暴露的组件(Stateful) class ColorChangeWidget extends StatefulWidget { final Animation<Color> animation; final VoidCallback? onCompleted; // 动画完成回调 const ColorChangeWidget({ Key? key, required this.animation, this.onCompleted, }) : super(key: key); @override _ColorChangeWidgetState createState() => _ColorChangeWidgetState(); } class _ColorChangeWidgetState extends State<ColorChangeWidget> { @override void initState() { super.initState(); // 初始化时添加状态监听 widget.animation.addStatusListener(_onAnimationStatusChanged); } @override void didUpdateWidget(covariant ColorChangeWidget oldWidget) { super.didUpdateWidget(oldWidget); // 如果动画对象被替换,移除旧监听,添加新监听 if (oldWidget.animation != widget.animation) { oldWidget.animation.removeStatusListener(_onAnimationStatusChanged); widget.animation.addStatusListener(_onAnimationStatusChanged); } } @override void dispose() { // 销毁时移除监听,防止内存泄漏 widget.animation.removeStatusListener(_onAnimationStatusChanged); super.dispose(); } void _onAnimationStatusChanged(AnimationStatus status) { if (status == AnimationStatus.completed) { widget.onCompleted?.call(); // 触发回调 } } @override Widget build(BuildContext context) { // 内部使用AnimatedWidget实现UI渲染 return _ColorChangeAnimatedWidget(animation: widget.animation); } } // 原来的AnimatedWidget(私有,只负责UI) class _ColorChangeAnimatedWidget extends AnimatedWidget { const _ColorChangeAnimatedWidget({required Animation<Color> animation}) : super(listenable: animation); @override Widget build(BuildContext context) { final anim = listenable as Animation<Color>; return Container( width: 200, height: 200, color: anim.value, ); } }
使用这个组件的时候,直接传入回调即可:
// 在父组件中 ColorChangeWidget( animation: _colorAnim, onCompleted: () { print("动画完成啦!执行自定义逻辑"); }, )
注意事项
- 一定要记得在组件销毁时移除动画状态监听,避免内存泄漏。
- 如果动画会被重复触发(比如反向播放再正向),可以根据
AnimationStatus.dismissed等其他状态处理逻辑。
内容的提问来源于stack exchange,提问作者majidfathi69
相关产品推荐
相关产品推荐

