颤动:动画过渡到命名路线
flutter: animate transition to named route
当我使用 Navigator.pushNamed(context, "/someRoute");
时,有一个最小的动画从屏幕底部在新路线中滑动(在 Android 上,在 iOS 上可能看起来不同)。
如何向此过渡添加自定义动画?
我发现 this article,它有一些非常简洁的 未命名 路由示例代码。他们实现了自己的 class,它继承自 PageRouteBuilder
,可以像这样使用:Navigator.push(context, SlideRightRoute(page: Screen2()))
。但是 PageRouteBuilder
不是 Widget,不能在 MaterialApp
中注册为路由。所以我不知道如何将其应用于命名路由。
您需要在 MaterialApp
小部件中使用 onGenerateRoute
。
onGenerateRoute: (settings) {
if (settings.name == "/someRoute") {
return PageRouteBuilder(
settings: settings, // Pass this to make popUntil(), pushNamedAndRemoveUntil(), works
pageBuilder: (_, __, ___) => SomePage(),
transitionsBuilder: (_, a, __, c) => FadeTransition(opacity: a, child: c)
);
}
// Unknown route
return MaterialPageRoute(builder: (_) => UnknownPage());
},
没有 onGenerateRoute
!
也可以使用动画路线
如果您使用 MaterialApp
的 routes
地图来定义您的命名路线,这里是您如何定义命名路线(其名称不会是 null
)。
只需通过扩展 PageRouteBuilder
:
创建您的路线
import 'package:flutter/material.dart';
class FadeInRoute extends PageRouteBuilder {
final Widget page;
FadeInRoute({this.page, String routeName})
: super(
settings: RouteSettings(name: routeName), // set name here
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(milliseconds: 500),
);
}
然后在导航时,只需执行以下操作:
Navigator.push( // or pushReplacement, if you need that
context,
FadeInRoute(
routeName: RouteNames.home,
page: MyHomeScreen(),
),
);
我找到了一个简单的解决方案(灵感来自 )
首先需要为MaterialApp设置一个静态的GlobalKey并导出
static GlobalKey mtAppKey = GlobalKey();
Widget build(BuildContext context) {
return MaterialApp(
key: MyApp.mtAppKey,
...
此外,您需要自定义 PageRouteBuilder 来处理它
空安全已禁用
class CustomNamedPageTransition extends PageRouteBuilder {
CustomNamedPageTransition(
GlobalKey materialAppKey,
String routeName, {
Object arguments,
}) : super(
settings: RouteSettings(
arguments: arguments,
name: routeName,
),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
assert(materialAppKey.currentWidget != null);
assert(materialAppKey.currentWidget is MaterialApp);
var mtapp = materialAppKey.currentWidget as MaterialApp;
var routes = mtapp.routes;
assert(routes.containsKey(routeName));
return routes[routeName](context);
},
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(seconds: 1),
);
}
空安全启用
class CustomNamedPageTransition extends PageRouteBuilder {
CustomNamedPageTransition(
GlobalKey materialAppKey,
String routeName, {
Object? arguments,
}) : super(
settings: RouteSettings(
arguments: arguments,
name: routeName,
),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
assert(materialAppKey.currentWidget != null);
assert(materialAppKey.currentWidget is MaterialApp);
var mtapp = materialAppKey.currentWidget as MaterialApp;
var routes = mtapp.routes;
assert(routes!.containsKey(routeName));
return routes![routeName]!(context);
},
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(seconds: 1),
);
}
然后,您可以使用
打开您命名的路线
Navigator.push(
context,
CustomNamedPageTransition(
MyApp.mtAppKey,
MyRoute.routeName,
),
);
或
Navigator.pushReplacement(
context,
CustomNamedPageTransition(
MyApp.mtAppKey,
MyRoute.routeName,
),
);
当我使用 Navigator.pushNamed(context, "/someRoute");
时,有一个最小的动画从屏幕底部在新路线中滑动(在 Android 上,在 iOS 上可能看起来不同)。
如何向此过渡添加自定义动画?
我发现 this article,它有一些非常简洁的 未命名 路由示例代码。他们实现了自己的 class,它继承自 PageRouteBuilder
,可以像这样使用:Navigator.push(context, SlideRightRoute(page: Screen2()))
。但是 PageRouteBuilder
不是 Widget,不能在 MaterialApp
中注册为路由。所以我不知道如何将其应用于命名路由。
您需要在 MaterialApp
小部件中使用 onGenerateRoute
。
onGenerateRoute: (settings) {
if (settings.name == "/someRoute") {
return PageRouteBuilder(
settings: settings, // Pass this to make popUntil(), pushNamedAndRemoveUntil(), works
pageBuilder: (_, __, ___) => SomePage(),
transitionsBuilder: (_, a, __, c) => FadeTransition(opacity: a, child: c)
);
}
// Unknown route
return MaterialPageRoute(builder: (_) => UnknownPage());
},
没有 onGenerateRoute
!
如果您使用 MaterialApp
的 routes
地图来定义您的命名路线,这里是您如何定义命名路线(其名称不会是 null
)。
只需通过扩展 PageRouteBuilder
:
import 'package:flutter/material.dart';
class FadeInRoute extends PageRouteBuilder {
final Widget page;
FadeInRoute({this.page, String routeName})
: super(
settings: RouteSettings(name: routeName), // set name here
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(milliseconds: 500),
);
}
然后在导航时,只需执行以下操作:
Navigator.push( // or pushReplacement, if you need that
context,
FadeInRoute(
routeName: RouteNames.home,
page: MyHomeScreen(),
),
);
我找到了一个简单的解决方案(灵感来自
首先需要为MaterialApp设置一个静态的GlobalKey并导出
static GlobalKey mtAppKey = GlobalKey();
Widget build(BuildContext context) {
return MaterialApp(
key: MyApp.mtAppKey,
...
此外,您需要自定义 PageRouteBuilder 来处理它
空安全已禁用
class CustomNamedPageTransition extends PageRouteBuilder {
CustomNamedPageTransition(
GlobalKey materialAppKey,
String routeName, {
Object arguments,
}) : super(
settings: RouteSettings(
arguments: arguments,
name: routeName,
),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
assert(materialAppKey.currentWidget != null);
assert(materialAppKey.currentWidget is MaterialApp);
var mtapp = materialAppKey.currentWidget as MaterialApp;
var routes = mtapp.routes;
assert(routes.containsKey(routeName));
return routes[routeName](context);
},
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(seconds: 1),
);
}
空安全启用
class CustomNamedPageTransition extends PageRouteBuilder {
CustomNamedPageTransition(
GlobalKey materialAppKey,
String routeName, {
Object? arguments,
}) : super(
settings: RouteSettings(
arguments: arguments,
name: routeName,
),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
assert(materialAppKey.currentWidget != null);
assert(materialAppKey.currentWidget is MaterialApp);
var mtapp = materialAppKey.currentWidget as MaterialApp;
var routes = mtapp.routes;
assert(routes!.containsKey(routeName));
return routes![routeName]!(context);
},
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity: animation,
child: child,
),
transitionDuration: Duration(seconds: 1),
);
}
然后,您可以使用
打开您命名的路线Navigator.push(
context,
CustomNamedPageTransition(
MyApp.mtAppKey,
MyRoute.routeName,
),
);
或
Navigator.pushReplacement(
context,
CustomNamedPageTransition(
MyApp.mtAppKey,
MyRoute.routeName,
),
);