Установить переход по умолчанию для 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
    ),
  ),
Другие вопросы по тегам