如何将Flutter Hero动画的默认曲线路径改为线性路径?
自定义Flutter Hero动画的线性移动路径
要让Hero动画沿线性路径移动,你需要自定义Hero的飞行控制器——默认的MaterialHeroFlightDirector会遵循Material Design的曲线路径规范,我们可以通过重写页面路由的相关方法来替换它的行为。
实现步骤:
- 自定义带线性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)!; } }
- 使用自定义路由跳转
在首页的跳转逻辑中,用LinearHeroPageRoute替代默认的MaterialPageRoute:
// 首页中触发跳转的代码 Navigator.push( context, LinearHeroPageRoute( builder: (context) => SecondPage(), // 你的第二页组件 ), );
原理说明:
默认的MaterialHeroFlightDirector会给Hero的飞行路径添加Material Design特有的曲线偏移和缓动效果。我们通过以下两点修改实现线性路径:
- 把动画曲线替换为
Curves.linear,消除速度变化的缓动 - 重写
computeFlightRect方法,直接使用矩形的线性插值,确保Hero从起始位置到目标位置沿直线移动
这样修改后,你的Hero动画就会严格沿直线路径完成过渡,完全符合线性运动的需求。
内容的提问来源于stack exchange,提问作者Stefan de Kraker
相关产品推荐
相关产品推荐

