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

如何将Flutter Hero动画的默认曲线路径改为线性路径?

自定义Flutter Hero动画的线性移动路径

要让Hero动画沿线性路径移动,你需要自定义Hero的飞行控制器——默认的MaterialHeroFlightDirector会遵循Material Design的曲线路径规范,我们可以通过重写页面路由的相关方法来替换它的行为。

实现步骤:

  1. 自定义带线性Hero路径的PageRoute
    创建一个MaterialPageRoute的子类,重写createHeroFlightDirector方法,返回自定义的飞行控制器,强制使用线性动画曲线和直线插值路径:
class LinearHeroPageRoute<T> extends MaterialPageRoute<T> {
  LinearHeroPageRoute({
    required WidgetBuilder builder,
    RouteSettings? settings,
    bool maintainState = true,
    bool fullscreenDialog = false,
  }) : super(
          builder: builder,
          settings: settings,
          maintainState: maintainState,
          fullscreenDialog: fullscreenDialog,
        );

  @override
  HeroFlightDirector createHeroFlightDirector() {
    return _LinearHeroFlightDirector();
  }
}

class _LinearHeroFlightDirector extends MaterialHeroFlightDirector {
  @override
  Animation<double> createAnimation(HeroFlight flight, Duration duration) {
    // 替换默认的Material曲线为线性曲线
    return CurvedAnimation(
      parent: super.createAnimation(flight, duration),
      curve: Curves.linear,
      reverseCurve: Curves.linear,
    );
  }

  @override
  Rect computeFlightRect(
      HeroFlight flight, Rect fromRect, Rect toRect, Animation<double> animation) {
    // 强制使用矩形的线性插值,确保移动路径是直线
    return Rect.lerp(fromRect, toRect, animation.value)!;
  }
}
  1. 使用自定义路由跳转
    在首页的跳转逻辑中,用LinearHeroPageRoute替代默认的MaterialPageRoute:
// 首页中触发跳转的代码
Navigator.push(
  context,
  LinearHeroPageRoute(
    builder: (context) => SecondPage(), // 你的第二页组件
  ),
);

原理说明:

默认的MaterialHeroFlightDirector会给Hero的飞行路径添加Material Design特有的曲线偏移和缓动效果。我们通过以下两点修改实现线性路径:

  • 把动画曲线替换为Curves.linear,消除速度变化的缓动
  • 重写computeFlightRect方法,直接使用矩形的线性插值,确保Hero从起始位置到目标位置沿直线移动

这样修改后,你的Hero动画就会严格沿直线路径完成过渡,完全符合线性运动的需求。

内容的提问来源于stack exchange,提问作者Stefan de Kraker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:53:10