Как перейти на другую страницу без анимации Flutter

У меня есть страница входа, когда я захожу на главную страницу своего приложения, которое я используюNavigator.pushReplacement(context, new MaterialPageRoute(builder: (BuildContext context) => new Page1()));Но у него есть анимация слайдов, я хочу отключить его.

это мой формат приложения Материал

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Login(title: 'Login'),
      routes: <String, WidgetBuilder>{
        '/screen3': (BuildContext context) => new Page1(),
      },
    );
  }
}

10 ответов

Ты можешь использовать PageRouteBuilder.

 Navigator.pushReplacement(
      context, 
      PageRouteBuilder(
        pageBuilder: (context, animation1, animation2) => Page1(),
    ),
);

Вам нужно будет переопределить buildTransitions метод предотвращения анимации.

class NoAnimationMaterialPageRoute<T> extends MaterialPageRoute<T> {
  NoAnimationMaterialPageRoute({
    @required WidgetBuilder builder,
    RouteSettings settings,
    bool maintainState = true,
    bool fullscreenDialog = false,
  }) : super(
            builder: builder,
            maintainState: maintainState,
            settings: settings,
            fullscreenDialog: fullscreenDialog);

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return child;
  }
}`

Вы можете переопределить MaterialPageRoute, чтобы установить transitionDuration равным нулю.

class CustomPageRoute extends MaterialPageRoute {
  CustomPageRoute({builder}) : super(builder: builder);

  @override
  Duration get transitionDuration => const Duration(milliseconds: 0);
}

...

Navigator.of(context).push(
  CustomPageRoute(
    builder: (BuildContext context) {
      return DashboardView();
    },
  ),
);

Убедитесь, что вы также установили transitionDuration в противном случае вы можете нажать новый маршрут без анимации, но когда вы нажмете кнопку возврата, вы увидите некоторую задержку.

Navigator.push(
  context,
  PageRouteBuilder(
    pageBuilder: (_, __, ___) => Screen2(),
    transitionDuration: Duration(seconds: 0),
  ),
);

Мое решение состоит в том, чтобы определить маршрут с isInitialRoute:true, Это не позволяет Flutter показывать анимацию при нажатии на маршрут.

Вот рабочий пример и запись экрана:

import 'package:flutter/cupertino.dart'
    show
        CupertinoApp,
        CupertinoButton,
        CupertinoPageRoute,
        CupertinoPageScaffold;
import 'package:flutter/widgets.dart'
    show
        BuildContext,
        Center,
        Column,
        Navigator,
        Route,
        RouteSettings,
        SafeArea,
        Spacer,
        Text,
        runApp,
        Widget;

Widget makeButton(BuildContext context, String routeName) =>
    new CupertinoButton(
      onPressed: () => Navigator.pushReplacementNamed(context, routeName),
      child: Text('Go to \'$routeName\''),
    );

Route generateRoute(RouteSettings settings) {
  switch (settings.name) {
    case 'not-animated':
      return new CupertinoPageRoute(
        settings: RouteSettings(name: settings.name, isInitialRoute: true),
        builder: (context) => CupertinoPageScaffold(
              child: SafeArea(
                child: Center(
                  child: Column(
                    children: [
                      Spacer(),
                      Text('This is \'not-animated\''),
                      makeButton(context, 'animated'),
                      Spacer(),
                    ],
                  ),
                ),
              ),
            ),
      );
    default:
      return null;
  }
}

void main() {
  runApp(
    CupertinoApp(
      onGenerateRoute: generateRoute,
      initialRoute: 'animated',
      routes: {
        'animated': (context) => CupertinoPageScaffold(
              child: SafeArea(
                child: Center(
                  child: Column(
                    children: [
                      Spacer(),
                      Text('This is \'animated\''),
                      makeButton(context, 'not-animated'),
                      Spacer(),
                    ],
                  ),
                ),
              ),
            ),
      },
    ),
  );
}

Если вы захотите использовать пакет get , вы можете отключить анимацию перехода с помощью свойства GetMaterialApp.

      GetMaterialApp(
  defaultTransition: Transition.noTransition, //this would be the solution
  transitionDuration: transitionDuration: Duration(seconds: 0),
);

А затем просто добавьте другие желаемые свойства.

Вы должны попытаться расширить MaterialPageRoute и переопределить buildTransitions следующим образом:

class ExPageRoute<T> extends MaterialPageRoute<T> {

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

В Navigator 2.0 есть два способа:

  1. Восстановите навигатор с новым pagesсписок, в котором был заменен последний элемент. Если предыдущая и замена Page у обоих нет ключа или один и тот же ключ, тогда Flutter будет рассматривать их как одну и ту же страницу и не будет анимировать.
  2. Набор Navigator.transitionDelegate к объекту, который простирается TransitionDelegate. Делегат должен проверить наличие новой записи с помощьюRouteTransitionRecord.isWaitingForEnteringDecision правда и назовите это markForAdd()метод. В https://github.com/flutter/flutter/issues/69315#issuecomment-833212172 есть полезный код .

Пример с навигатором 2.0 без анимации

      import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

var userName = '';
var password = '';

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(context) {
    return MaterialApp(
      home: Navigator(
        transitionDelegate: NoAnimationTransitionDelegate(),
        pages: [
          MaterialPage(child: HomePage()),
          if (password.isEmpty) MaterialPage(child: PasswordPage()),
          if (userName.isEmpty) MaterialPage(child: UserNamePage()),
        ],
        onPopPage: (route, result) {
          if (!route.didPop(result)) return false;
          return true;
        },
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(context) {
    return Scaffold(backgroundColor: Colors.blue);
  }
}

class PasswordPage extends StatelessWidget {
  @override
  Widget build(context) {
    return Scaffold(backgroundColor: Colors.amber);
  }
}

class UserNamePage extends StatelessWidget {
  @override
  Widget build(context) {
    return Scaffold(backgroundColor: Colors.green);
  }
}

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 results = <RouteTransitionRecord>[];

    for (final pageRoute in newPageRouteHistory) {
      if (pageRoute.isWaitingForEnteringDecision) {
        pageRoute.markForAdd();
      }
      results.add(pageRoute);
    }

    for (final exitingPageRoute in locationToExitingPageRoute.values) {
      if (exitingPageRoute.isWaitingForExitingDecision) {
        exitingPageRoute.markForRemove();
        final pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
        if (pagelessRoutes != null) {
          for (final pagelessRoute in pagelessRoutes) {
            pagelessRoute.markForRemove();
          }
        }
      }
      results.add(exitingPageRoute);
    }

    return results;
  }
}

Это без переходов. Только переход на следующую страницу

      class FadeInPageRoute<T> extends PageRoute<T> {
  FadeInPageRoute({
    RouteSettings? settings,
    required this.builder,
  }) : super(settings: settings);

  final WidgetBuilder builder;

  @override
  Color get barrierColor => Colors.black;

  @override
  String get barrierLabel => '';

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return builder(context);
  }

  @override
  bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
    return false;
  }

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return Opacity(
      opacity: animation.value,
      child: builder(context),
    );
  }

  @override
  bool get maintainState => true;

  @override
  Duration get transitionDuration => Duration(milliseconds: 700);
}

Другие вопросы по тегам