如何自定义Flutter的CupertinoPageRoute返回动画方向?
自定义Flutter Cupertino导航返回动画(右滑入效果)
要实现返回操作时页面从右侧滑入的效果,无需重新推送Page1,可通过以下两种方式实现:
方法一:继承CupertinoPageRoute重写过渡动画
直接修改CupertinoPageRoute的pop阶段过渡逻辑,保持push动画默认,替换pop动画方向:
class ReversePopCupertinoRoute<T> extends CupertinoPageRoute<T> { ReversePopCupertinoRoute({ required WidgetBuilder builder, RouteSettings? settings, bool maintainState = true, bool fullscreenDialog = false, }) : super( builder: builder, settings: settings, maintainState: maintainState, fullscreenDialog: fullscreenDialog, ); @override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { // Push时保持默认的右滑入动画 if (animation.status == AnimationStatus.forward) { return super.buildTransitions(context, animation, secondaryAnimation, child); } // Pop时修改动画:当前页面左滑出,上一页从右滑入 else { return CupertinoPageTransition( primaryRouteAnimation: animation, secondaryRouteAnimation: ReverseAnimation(animation), linearTransition: linearTransition, child: child, ); } } }
使用方式
跳转Page2时使用自定义路由:
Navigator.push( context, ReversePopCupertinoRoute(builder: (context) => Page2()), );
返回Page1时直接调用默认pop:
Navigator.pop(context);
方法二:用PageRouteBuilder自定义完整过渡
通过PageRouteBuilder同时定义push和pop的动画逻辑,更灵活可控:
Route customSlideRoute(Widget page) { return PageRouteBuilder( transitionDuration: Duration(milliseconds: 300), // 对齐Cupertino默认时长 pageBuilder: (context, animation, secondaryAnimation) => page, transitionsBuilder: (context, animation, secondaryAnimation, child) { // Push动画:新页面从右到左滑入 final pushTween = Tween<Offset>( begin: Offset(1.0, 0.0), end: Offset.zero, ).animate(CurvedAnimation(parent: animation, curve: Curves.easeInOut)); // Pop动画:当前页面左滑出,上一页右滑入 final popOutTween = Tween<Offset>( begin: Offset.zero, end: Offset(-1.0, 0.0), ).animate(CurvedAnimation(parent: secondaryAnimation, curve: Curves.easeInOut)); final popInTween = Tween<Offset>( begin: Offset(1.0, 0.0), end: Offset.zero, ).animate(CurvedAnimation(parent: secondaryAnimation, curve: Curves.easeInOut)); return Stack( children: [ // 上一页的pop入场动画 SlideTransition( position: popInTween, child: ModalRoute.of(context)?.previousContentWidget ?? SizedBox.shrink(), ), // 当前页面的push/pop动画 SlideTransition( position: animation.status == AnimationStatus.forward ? pushTween : popOutTween, child: child, ), ], ); }, ); }
使用方式
跳转和返回逻辑与方法一完全一致:
// 跳转Page2 Navigator.push(context, customSlideRoute(Page2())); // 返回Page1 Navigator.pop(context);
两种方案都无需重新推送Page1,通过修改路由过渡动画即可实现你要的PageView式切换效果。
内容的提问来源于stack exchange,提问作者Samir Omerbegovic
相关产品推荐
相关产品推荐

