在 Flutter 中设置 go_router 的默认转换

问题描述 投票:0回答:5

正如 go_router 的文档所描述的,很容易设置 pageBuilder

-单个页面的转换。
但是,我想为
所有页面设置默认的 PageTransition。

如何在 Flutter 中使用 go_router 设置默认页面转换?

单页:

// this is the proposed method to do it for single pages // how can i apply it to all pages without writing the same code? GoRoute( path: '/login', builder: (context, state) => const LoginScreen(), pageBuilder: (context, state) => CustomTransitionPage<void>( key: state.pageKey, child: const LoginScreen(), transitionsBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(opacity: animation, child: child), ), ),
致以诚挚的问候

flutter animation navigation transition gorouter
5个回答
22
投票

go_router

包目前不支持此功能,但为了减少代码重复,您可以创建一个辅助函数来为您的路线应用自定义转换,例如:

CustomTransitionPage buildPageWithDefaultTransition<T>({ required BuildContext context, required GoRouterState state, required Widget child, }) { return CustomTransitionPage<T>( key: state.pageKey, child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(opacity: animation, child: child), ); } <...> GoRoute( path: '/login', builder: (context, state) => const LoginScreen(), pageBuilder: (context, state) => buildPageWithDefaultTransition<void>( context: context, state: state, child: LoginScreen(), ), ),
    

7
投票
更正确的方式是继承自

CustomTransitionPage

class WebPage extends CustomTransitionPage { WebPage({ LocalKey key, ... // other properties taken from `MaterialPage` required Widget child }) : super( key: key, transitionBuilder: (...) { return FadeTransition(...); } child: child, // Here you may also wrap this child with some common designed widget ); }
然后

GoRoute( path: '/login', pageBuilder: (context, state) => WebPage( key: state.pageKey, child: const LoginScreen(), ), ),
    

3
投票
扩展@mkobuolys答案,可以通过返回创建页面构建器的函数进一步减少样板,即:

CustomTransitionPage buildPageWithDefaultTransition<T>({ required BuildContext context, required GoRouterState state, required Widget child, }) { return CustomTransitionPage<T>( key: state.pageKey, child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(opacity: animation, child: child), ); } Page<dynamic> Function(BuildContext, GoRouterState) defaultPageBuilder<T>( Widget child) => (BuildContext context, GoRouterState state) { return buildPageWithDefaultTransition<T>( context: context, state: state, child: child, ); };
路由器看起来像:

final _router = GoRouter( routes: [ GoRoute( path: '/a', builder: (context, state) => const PageA(), pageBuilder: defaultPageBuilder(const PageA()), ), GoRoute( path: '/b', builder: (context, state) => const PageB(), pageBuilder: defaultPageBuilder(const PageB()), ), ], );
    

2
投票
下面是过渡工厂的代码(很大程度上基于@mkobuolys的答案)。它还添加了 3 种过渡效果:

scale

rotation
size

Rotation

按照我的口味转了太多次,
size
看起来几乎没有过渡效果,但是
scale
还不错。

import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class RouterTransitionFactory { static CustomTransitionPage getTransitionPage( {required BuildContext context, required GoRouterState state, required Widget child, required String type}) { return CustomTransitionPage( key: state.pageKey, child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) { switch (type) { case 'fade': return FadeTransition(opacity: animation, child: child); case 'rotation': return RotationTransition(turns: animation, child: child); case 'size': return SizeTransition(sizeFactor: animation, child: child); case 'scale': return ScaleTransition(scale: animation, child: child); default: return FadeTransition(opacity: animation, child: child); } }); } }
应该这样称呼:

GoRoute( path: '/settings', builder: (context, state) => const Settings(), //StatelessWidget pageBuilder: (context, state) => RouterTransitionFactory.getTransitionPage( context: context, state: state, child: const Settings(), type: 'scale', // fade|rotation|scale|size ), ),
    

0
投票
为什么不这样使用它比接受的答案更容易

GoRoute defaultTransitionGoRoute({ required String path, required Widget Function(BuildContext, GoRouterState) pageBuilder, }) { return GoRoute( path: path, pageBuilder: (context, state) => CustomTransitionPage<void>( key: state.pageKey, transitionDuration: const Duration(milliseconds: 300), child: pageBuilder(context, state), transitionsBuilder: (context, animation, secondaryAnimation, child) { return FadeTransition( opacity: CurveTween(curve: Curves.easeIn).animate(animation), child: child, ); }, ), ); }
然后使用like

GoRoute( path: ScreenPaths.favorites, builder: (context, state) => FavorateScreen(), ), defaultTransitionGoRoute( path: ScreenPaths.viewEmail, pageBuilder: (context, state) { final extra = state.extra; return ViewEmailScreen( email: extra as HiveEmail, ); }, ),
    
© www.soinside.com 2019 - 2024. All rights reserved.