如何在Flutter GoRouter中添加动画,动画类能否独立存放调用
在Flutter GoRouter中添加页面切换动画及独立动画类实现
一、添加页面切换动画
GoRouter中自定义页面过渡需要用pageBuilder替代原代码中的builder,通过CustomTransitionPage配置过渡动画。以下是基于你提供的示例修改后的代码:
void main() => runApp(App()); class App extends StatelessWidget { App({Key? key}) : super(key: key); static const String title = 'GoRouter Example: Declarative Routes'; @override Widget build(BuildContext context) => MaterialApp.router( routerConfig: _router, title: title, ); final GoRouter _router = GoRouter( routes: <GoRoute>[ GoRoute( path: '/', // 用pageBuilder替代builder,自定义过渡动画 pageBuilder: (BuildContext context, GoRouterState state) => CustomTransitionPage( child: const Page1Screen(), transitionsBuilder: (context, animation, secondaryAnimation, child) { // 定义从右侧滑入的动画 var begin = const Offset(1.0, 0.0); var end = Offset.zero; var curve = Curves.ease; var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ), routes: <GoRoute>[ GoRoute( path: 'page2', pageBuilder: (BuildContext context, GoRouterState state) => CustomTransitionPage( child: const Page2Screen(), transitionsBuilder: (context, animation, secondaryAnimation, child) { // 定义淡入动画 return FadeTransition( opacity: animation.drive(Tween(begin: 0.0, end: 1.0).chain(CurveTween(curve: Curves.easeInOut))), child: child, ); }, ), ), ], ), ], ); }
二、将动画类存放在独立文件中
完全可以把动画逻辑封装到独立文件中,方便复用和管理。创建一个route_transitions.dart文件,把不同的动画封装成自定义CustomTransitionPage子类:
// route_transitions.dart import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; // 右侧滑入动画页面 class SlideRightTransitionPage extends CustomTransitionPage { SlideRightTransitionPage({required Widget child}) : super( child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin = Offset(1.0, 0.0); const end = Offset.zero; const curve = Curves.ease; final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ); } // 淡入淡出动画页面 class FadeTransitionPage extends CustomTransitionPage { FadeTransitionPage({required Widget child}) : super( child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) { return FadeTransition( opacity: animation.drive(Tween(begin: 0.0, end: 1.0).chain(CurveTween(curve: Curves.easeInOut))), child: child, ); }, ); } // 缩放动画页面 class ScaleTransitionPage extends CustomTransitionPage { ScaleTransitionPage({required Widget child}) : super( child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) { return ScaleTransition( scale: animation.drive(Tween(begin: 0.8, end: 1.0).chain(CurveTween(curve: Curves.easeOut))), child: child, ); }, ); }
之后在主文件中导入该文件,直接在路由中使用这些动画类:
import 'route_transitions.dart'; // ... final GoRouter _router = GoRouter( routes: <GoRoute>[ GoRoute( path: '/', pageBuilder: (_, __) => SlideRightTransitionPage(child: const Page1Screen()), routes: <GoRoute>[ GoRoute( path: 'page2', pageBuilder: (_, __) => FadeTransitionPage(child: const Page2Screen()), ), GoRoute( path: 'page3', pageBuilder: (_, __) => ScaleTransitionPage(child: const Page3Screen()), ), ], ), ], );
额外说明
- 你可以给动画类添加参数(比如动画时长、曲线),让动画配置更灵活
- 如果需要全局默认过渡动画,可在GoRouter初始化时配置
pageBuilder,个别路由再单独覆盖
内容的提问来源于stack exchange,提问作者George-Goldman
相关产品推荐
相关产品推荐

