Как перейти на другую страницу без анимации 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 есть два способа:
- Восстановите навигатор с новым
pages
список, в котором был заменен последний элемент. Если предыдущая и заменаPage
у обоих нет ключа или один и тот же ключ, тогда Flutter будет рассматривать их как одну и ту же страницу и не будет анимировать. - Набор
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);
}