如何去除默认导航路线动画

How to remove default navigation route animation

我在 flutter 文档中给出的页面路由代码下面

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

但是它在推送和弹出路由时提供了一些动画。

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.)

有什么方法可以在没有任何动画的情况下转到下一页吗?

编辑: 请检查整个代码:

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!'),
        ),
      ),
    );
  }
}

动画由MaterialPageRoute执行。如果你不想要它,简单地使用其他东西:

Navigator.push(
  context,
  PageRouteBuilder(pageBuilder: (_, __, ___) => MyRoute()),
)
  • 对于Navigator.push(...)

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

    首先,将此添加到您的 MaterialApp

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

    现在,您可以使用:

    Navigator.pushNamed(context, '/second');
    

用这个替换你的MyApp

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;
      },
    );
  }
}

由于 Flutter 现在正在迁移到 Navigator 2.0 以获得更多支持,我建议查看他们的 migration guide 以向 Navigator 添加 TransitionDelegate。将此 class 的一个实例添加到您的导航器以实现预期结果:

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 marshal 的解决方案很简单并且工作正常但他的代码有一些调整

 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;
   }
  }
 }