Flutter中两个GoRoute使用pageBuilder时过渡动画失效问题
问题解答
1. 实现A与B双向淡入淡出过渡的方案
你需要在CustomTransitionPage的transitionsBuilder中同时处理新页面的进入动画和旧页面的退出动画,通过Stack将两个页面的动画逻辑结合,确保双向切换都能呈现淡入淡出效果。修改后的路由配置如下:
final routes = GoRouter(routes: <RouteBase>[ GoRoute( path: "/A", pageBuilder: (context, state) => CustomTransitionPage( child: const ViewA(), transitionDuration: const Duration(seconds: 2), transitionsBuilder: (context, animation, secondaryAnimation, child) => Stack( children: [ // 旧页面退出动画:反向利用secondaryAnimation实现淡出 if (secondaryAnimation.status != AnimationStatus.dismissed) FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc) .animate(ReverseAnimation(secondaryAnimation)), child: context.findAncestorWidgetOfExactType<CustomTransitionPage>()?.child, ), // 新页面进入动画:用animation控制淡入 FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc).animate(animation), child: child, ), ], ), ), ), GoRoute( path: "/B", pageBuilder: (context, state) => CustomTransitionPage( child: const ViewB(), transitionDuration: const Duration(seconds: 2), transitionsBuilder: (context, animation, secondaryAnimation, child) => Stack( children: [ if (secondaryAnimation.status != AnimationStatus.dismissed) FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc) .animate(ReverseAnimation(secondaryAnimation)), child: context.findAncestorWidgetOfExactType<CustomTransitionPage>()?.child, ), FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc).animate(animation), child: child, ), ], ), ), ), ]);
如果想简化代码,可以把过渡逻辑抽成复用函数:
Widget _fadeTransitionBuilder(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { return Stack( children: [ if (secondaryAnimation.status != AnimationStatus.dismissed) FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc) .animate(ReverseAnimation(secondaryAnimation)), child: context.findAncestorWidgetOfExactType<CustomTransitionPage>()?.child, ), FadeTransition( opacity: CurveTween(curve: Curves.easeInOutCirc).animate(animation), child: child, ), ], ); }
之后在两个路由的transitionsBuilder中直接调用该函数即可。
2. 双路由配置过渡动画后失效的原因
当两个路由都使用CustomTransitionPage时,context.go属于替换路由栈的操作,GoRouter会同时触发旧页面的退出动画和新页面的进入动画。但你最初的代码只处理了新页面的进入(仅用animation控制透明度),完全没有利用secondaryAnimation处理旧页面的退出逻辑。
这种情况下,新旧页面的动画叠加后,视觉上呈现为直接切换,看不到任何过渡效果。而当其中一个路由用builder(默认MaterialPage)时,GoRouter会用默认过渡逻辑配合自定义页面的动画,所以能看到单向的淡入效果。
内容的提问来源于stack exchange,提问作者Felix ZY
相关产品推荐
相关产品推荐

