17

I am below code which given in flutter documentation for page routing

// Within the `FirstRoute` widget
onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),
  );
}

But it provides some animation while pushing and poping route.

For Android, the entrance transition for the page slides the page upwards and fades it in. The exit transition is the same, but in reverse.

The transition is adaptive to the platform and on iOS, the page slides in from the right and exits in reverse. The page also shifts to the left in parallax when another page enters to cover it. (These directions are flipped in environments with a right-to-left reading direction.)

Is there any way to route to next page without any animation?

Edit: Please check the entire code:

class MyApp extends StatelessWidget {
  final routes = <String, WidgetBuilder>{
    SecondRoute.tag: (context) => SecondRoute(),
  };

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter Routes",
      home: new FirstRoute(),
      routes: routes,
      onGenerateRoute: (routeSettings) {
        if (routeSettings.name == SecondRoute.tag)
          return PageRouteBuilder(pageBuilder: (_, a1, a2) => SecondRoute());

        return null;
      },
    );
  }
}

class FirstRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Open route'),
          onPressed: () {
            Navigator.of(context).pushNamed(SecondRoute.tag);

          },
        ),
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  static String tag = 'second-route';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147

7 Answers7

27
  • For Navigator.push(...)

    Navigator.push(
      context,
      PageRouteBuilder(pageBuilder: (_, __, ___) => SecondRoute()),
    )
    
  • For Navigator.pushNamed(...)

    First, add this to your MaterialApp

    MaterialApp(
      onGenerateRoute: (settings) {
        if (settings.name == '/second') 
          return PageRouteBuilder(pageBuilder: (_, __, ___) => SecondRoute());
    
        return null;
      },
    )
    

    And now, you can use:

    Navigator.pushNamed(context, '/second');
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
11

The animation is performed by MaterialPageRoute. If you don't want it, simple use something else:

Navigator.push(
  context,
  PageRouteBuilder(pageBuilder: (_, __, ___) => MyRoute()),
)
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
3

As Flutter is now migrating to Navigator 2.0 for increased support, I would recommend checking out their migration guide on adding a TransitionDelegate to the Navigator. Add an instance of this class to your navigator to achieve the intended result:

import 'package:flutter/widgets.dart';

class NoAnimationTransitionDelegate extends TransitionDelegate<void> {
  @override
  Iterable<RouteTransitionRecord> resolve({
    List<RouteTransitionRecord> newPageRouteHistory,
    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
  }) {
    final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];

    for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
      // Renames isEntering to isWaitingForEnteringDecision.
      if (pageRoute.isWaitingForEnteringDecision) {
        pageRoute.markForAdd();
      }
      results.add(pageRoute);

    }
    for (final RouteTransitionRecord exitingPageRoute in locationToExitingPageRoute.values) {
      // Checks the isWaitingForExitingDecision before calling the markFor methods.
      if (exitingPageRoute.isWaitingForExitingDecision) {
        exitingPageRoute.markForRemove();
        final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
        if (pagelessRoutes != null) {
          for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
            pagelessRoute.markForRemove();
          }
        }
      }
      results.add(exitingPageRoute);

    }
    return results;
   }
 }
Aidan Marshall
  • 521
  • 6
  • 16
2

Replace your MyApp with this.

class MyApp extends StatelessWidget {
  final routes = <String, WidgetBuilder>{SecondRoute.tag: (context) => SecondRoute()};

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter Routes",
      home: new FirstRoute(),
      onGenerateRoute: (routeSettings) {
        if (routeSettings.name == SecondRoute.tag)
          return PageRouteBuilder(
            pageBuilder: (_, a1, a2) => FadeTransition(opacity: a1 ,child: SecondRoute()),
            transitionDuration: Duration(seconds: 5),
          );

        return null;
      },
    );
  }
}
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
0

aidan marshal's solution is simple and works fine but there some adjustments in his code

 import 'package:flutter/widgets.dart';

class NoAnimationTransitionDelegate extends TransitionDelegate<void> {

   @override
   Iterable<RouteTransitionRecord> resolve({
       required List<RouteTransitionRecord> newPageRouteHistory,
       required Map<RouteTransitionRecord?, RouteTransitionRecord> 
       locationToExitingPageRoute, required Map<RouteTransitionRecord?, 
      List<RouteTransitionRecord>> pageRouteToPagelessRoutes}) {
    {
     final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];

     for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
      // Renames isEntering to isWaitingForEnteringDecision.
      if (pageRoute.isWaitingForEnteringDecision) {
        pageRoute.markForAdd();
      }
      results.add(pageRoute);

    }
    for (final RouteTransitionRecord exitingPageRoute in locationToExitingPageRoute.values) {
      // Checks the isWaitingForExitingDecision before calling the markFor methods.
      if (exitingPageRoute.isWaitingForExitingDecision) {
        exitingPageRoute.markForRemove();
        final List<RouteTransitionRecord>? pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
        if (pagelessRoutes != null) {
          for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
            pagelessRoute.markForRemove();
          }
        }
      }
      results.add(exitingPageRoute);

    }
    return results;
   }
  }
 }
bk3
  • 41
  • 3
0

If you are using routs, here is the full code to get the permanent solution

      void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await ScreenUtil.ensureScreenSize();
      await ServiceLocator.setUpServiceLocator();
      initializeLoggerServer();
      serviceLocator.get<Log>().shout('App Initialized Successfully');
      runApp(AgrotopiaApp());
    }
    
    void initializeLoggerServer() {
      Logger.root.level = Level.ALL; // defaults to Level.INFO
      Logger.root.onRecord.listen((record) {
        debugPrint('${record.level.name}: ${record.time}: ${record.message}');
      });
    }
      //create this class to make no animation 
    class NoAnimationPageRoute<T> extends MaterialPageRoute<T> {
      NoAnimationPageRoute({required WidgetBuilder builder, required RouteSettings settings})
          : super(builder: builder, settings: settings);
    
      @override
      Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
        return FadeTransition(opacity: AlwaysStoppedAnimation(1.0), child: child);
      }
    }
    
   
    class FadePageRoute<T> extends MaterialPageRoute<T> {
      FadePageRoute({required WidgetBuilder builder, required RouteSettings settings})
          : super(builder: builder, settings: settings);
    
      @override
      Widget buildTransitions(BuildContext context, Animation<double> animation,
          Animation<double> secondaryAnimation, Widget child) {
        return FadeTransition(opacity: animation, child: child);
      }
    }
    
    
    class AgrotopiaApp extends StatelessWidget {
      AgrotopiaApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return ScreenUtilInit(
            designSize: context.resources.variables.screenDesignSize,
            splitScreenMode: false,
            minTextAdapt: true,
            useInheritedMediaQuery: false,
            builder: (BuildContext context, Widget? child) {
              return MultiProvider(
                providers: [
                  ChangeNotifierProvider(
                      create: (_) => LoaderModelView(), lazy: true),
                  ChangeNotifierProvider(
                      create: (_) => GlobalAppProvider(), lazy: true),
                  ChangeNotifierProvider(
                      create: (_) => OnBoardingViewModel(), lazy: true),
                  ChangeNotifierProvider(
                      create: (_) => BottomNavViewModel(), lazy: true),
                  ChangeNotifierProvider(
                      create: (_) => PlaceOrderViewModel(), lazy: true),
                  ChangeNotifierProvider(
                      create: (_) => PaymentViewModel(), lazy: true),
                ],
                child: MaterialApp(
                    navigatorKey: GlobalKey<NavigatorState>(),
                    title: context.resources.variables.appName,
                    debugShowCheckedModeBanner: false,
                    theme: context.resources.styles.appTheme(),
                    home: const SplashScreen(),
                    // home: CollectUserData(),
                    // home: const UserOnBoardingPage(),
                    initialRoute: '/',
                     onGenerateRoute: (RouteSettings settings) {
                      
            switch (settings.name) {
              
              case '/home':
                return NoAnimationPageRoute(builder: (_) => HomePage(), settings: settings);
              case '/app':
                return NoAnimationPageRoute(builder: (_) => AgrotopiaApp(), settings: settings);
              case '/settingpage':
                return NoAnimationPageRoute(builder: (_) => SettingPage(), settings: settings);
              case '/placeordermenu':
                return NoAnimationPageRoute(builder: (_) => PlaceOrderMenu(), settings: settings);
              case '/placeorderpage':
                return NoAnimationPageRoute(builder: (_) => PlaceOrderPage(), settings: settings);
              case '/paymentinformationpage':
                return NoAnimationPageRoute(builder: (_) => PaymentInformationPage(), settings: settings);
              case '/orderstatuspage':
                return NoAnimationPageRoute(builder: (_) => OrderStatusPage(), settings: settings);
              case '/orderdetailspage':
                return NoAnimationPageRoute(builder: (_) => OrderDetailsPage(), settings: settings);
              case '/confirmation':
                return NoAnimationPageRoute(builder: (_) => Confirmation(), settings: settings);
              // case '/orderdetailspage':
              //   return NoAnimationPageRoute(builder: (_) => OrderDetailsPage(), settings: settings);
              default:
                return MaterialPageRoute(builder: (_) => Scaffold());
            }
          },
                    
            
                    ),
              );
            });
      }
    }

now do navigate to another page

  Navigator.pushNamed(context,'/orderstatuspage');
Niaj Mahmud
  • 399
  • 3
  • 10
0

Remove it at Material Configuration level:

First, create a custom Page Transition (with no transition at all)

class _NoTransitionsBuilder extends PageTransitionsBuilder {
  const _NoTransitionsBuilder();

  @override
  Widget buildTransitions<T>(
    PageRoute<T>? route,
    BuildContext? context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget? child,
  ) {
    return child!;
  }
}

Then create a PageTransitionsTheme:

PageTransitionsTheme _removeTransitions() {
  return PageTransitionsTheme(
    builders: {
      for (final platform in TargetPlatform.values)
        platform: const _NoTransitionsBuilder(),
    },
  );
}

Finally, add the new Transitions Theme on your MaterialApp constructor

@override
Widget build(BuildContext context) {
  return MaterialApp(
    // ...
    theme: ThemeData(
      pageTransitionsTheme: _removeTransitions(),
    ),
  );
}
Yasser Nascimento
  • 1,302
  • 7
  • 13