【发布时间】:2026-01-03 20:40:01
【问题描述】:
我正在通过onGenerateRoute 设置我的路线和过渡动画,这很好用,除了我想要根据条件(例如在选择的路径上)不同的过渡动画:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return PageRouteBuilder<dynamic>(
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) =>
Page1(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return SlideTransition(
position: Tween<Offset>(
begin: Offset.zero,
end: const Offset(-1.0, 0.0),
).animate(secondaryAnimation), // Here I want to have differents transitions
child: child,
);
},
);
} else if (settings.name == '/second') {
return PageRouteBuilder<dynamic>(
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) =>
Page2(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(1.0, 0.0), end: Offset.zero)
.animate(animation),
child: SlideTransition(
position: Tween<Offset>(
begin: Offset.zero,
end: const Offset(0.0, 1.0),
).animate(secondaryAnimation),
child: child,
));
},
);
} else if (settings.name == '/third') {
return PageRouteBuilder<dynamic>(
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) =>
Page3(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0.0, 1.0), end: Offset.zero)
.animate(animation),
child: SlideTransition(
position: Tween<Offset>(
begin: Offset.zero,
end: const Offset(0.0, 1.0),
).animate(secondaryAnimation),
child: child,
));
},
);
} else {
return null;
}
},
);
}
}
class Page1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page 1"), backgroundColor: Colors.blue),
backgroundColor: Colors.blue,
body: Column(
children: [
Center(
child: RaisedButton(
onPressed: () => Navigator.pushNamed(context, '/second'),
child: Text("Go to Page 2 with exit transition slide left"),
),
),
Center(
child: RaisedButton(
onPressed: () => Navigator.pushNamed(context, '/third'),
child: Text("Go to Page 3 with transition slide top"),
),
),
],
),
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page 2"), backgroundColor: Colors.green),
backgroundColor: Colors.green,
body: Center(
child: RaisedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Go back to page 1"))),
);
}
}
class Page3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page 3"), backgroundColor: Colors.yellow),
backgroundColor: Colors.yellow,
body: Center(
child: RaisedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Go back to page 1"))),
);
}
}
由于在屏幕显示之前设置了退出过渡动画(通过secondaryAnimation),因此我无法根据单击的按钮动态更改动画。我怎样才能做到这一点?
【问题讨论】:
-
您可以通过导航器传递一个参数,在 PageRouteBuilder 中接受它,然后根据 switch 语句更改转换。
-
@ScottGodfrey 我说的是在路由调用期间由 secondaryAnimation 设置的退出过渡动画(因此以及离开屏幕创建的开始),没有办法知道哪个按钮会此刻被点击
-
你不能改变实际的过渡,但你可以改变它的动画效果。在返回 SlideTransition 之前,您可以更改动画和辅助动画。 secondaryAnimation = //新动画。
-
是的,我知道,问题是如何根据单击的按钮获得 2 种不同的退出动画?请看codePen试用一下
-
发表了答案。