You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:34:46