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

Flutter中如何为Wrap组件内的项添加增删动画?

在Flutter中实现Wrap子项增删时的动画填充效果

默认的Wrap组件在增删子项时没有过渡动画,要实现子项平滑移动并自动填充空间的效果,可通过以下两种方式实现:

方案一:用第三方动画包快速实现

推荐使用flutter_staggered_animations包,它专门为流式布局(比如Wrap、GridView)提供了开箱即用的 stagger 动画效果:

  1. 先在pubspec.yaml中添加依赖:
dependencies:
  flutter_staggered_animations: ^1.1.1
  1. 改造原Wrap代码,用动画组件包裹子项:
AnimationConfiguration.synchronized(
  duration: const Duration(milliseconds: 300), // 动画时长
  child: Wrap(
    direction: Axis.vertical,
    runAlignment: WrapAlignment.center,
    alignment: WrapAlignment.start,
    children: listItems.map((e) {
      return SlideAnimation(
        horizontalOffset: 50.0, // 水平滑动偏移量
        child: FadeAnimation(
          child: CustomWidget(data: e),
        ),
      );
    }).toList(),
  ),
)

这样增删子项时,子项会同时执行淡入淡出和滑动动画,并且自动填充空出来的空间,效果流畅自然。

方案二:自定义动画逻辑(不依赖第三方)

如果不想引入第三方包,可以结合AnimatedSwitcher和Wrap实现基础动画:

AnimatedSwitcher(
  duration: const Duration(milliseconds: 300),
  transitionBuilder: (child, animation) {
    // 自定义过渡动画:淡入+向下滑动
    return FadeTransition(
      opacity: animation,
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, 0.2),
          end: Offset.zero,
        ).animate(animation),
        child: child,
      ),
    );
  },
  child: Wrap(
    key: ValueKey(listItems.length), // 长度变化时触发动画
    direction: Axis.vertical,
    runAlignment: WrapAlignment.center,
    alignment: WrapAlignment.start,
    children: listItems.map((e) => CustomWidget(data: e)).toList(),
  ),
)

这里通过给Wrap设置ValueKey,当子项数量变化时,AnimatedSwitcher会触发预设的过渡动画。

进阶自定义:子项位置跟踪动画

如果需要子项从原位置平滑滑到新位置的效果,需要手动记录每个子项的位置:

  1. 给每个CustomWidget绑定GlobalKey,通过RenderBox获取子项的坐标;
  2. 当列表变化时,计算新旧位置的偏移量;
  3. 用TweenAnimationBuilder驱动子项的位置动画。
    这种方式灵活性更高,但代码量会增加,适合对动画效果有精细要求的场景。

内容的提问来源于stack exchange,提问作者Rajaghaneshan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:31:05