Установить переход по умолчанию для go_router во Flutter
как описано в документах go_router , легко установить
pageBuilder
-Переходы для отдельных страниц. Однако я хочу установить PageTransition по умолчанию для всех страниц.
Как установить переход страницы по умолчанию с помощью / для go_router во Flutter?
Одна страница:
// 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),
),
),
С наилучшими пожеланиями
4 ответа
Почему бы не использовать это проще, чем принятый ответ?
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,
);
},
),
);
}
тогда используйте лайк
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,
);
},
),
Более правильный путь - наследование от
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',
builder: (context, state) => const LoginScreen(),
pageBuilder: (context, state) => WebPage(
key: state.pageKey,
child: const LoginScreen(),
),
),
Расширяя ответ @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()),
),
],
);
Ниже приведен код фабрики переходов (в значительной степени основанный на ответе @mkobuolys). Он добавляет еще 3 эффекта перехода: ,rotation
, и .
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
),
),