您可以从onGenerateRoute 获取所有内容(路径、参数等)。您的 Home 将是 /,并且可以抓取那里的所有内容并用于重定向用户。
我解决这个问题的方法如下。您的基础 App() 应该是:
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Website Title',
onGenerateRoute: (settings) => NavigatorRoute.route(settings.name),
);
}
}
类 NavigatorRoute将是:
class NavigatorRoute extends StatefulWidget {
final String path;
static Route<dynamic> route(String path) {
return SimpleRoute(
name: '', // this one is always empty as you didn't route yet
title: 'Website Title',
builder: (_) => NavigatorRoute(path: path),
animated: false
);
}
const NavigatorRoute({Key key, this.path}) : super(key: key);
@override
_NavigatorRouteState createState() => _NavigatorRouteState();
}
class _NavigatorRouteState extends State<NavigatorRoute> {
@override
void initState() {
super.initState();
Future.microtask(() {
if (widget.path == '/') {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(false), (_) => false);
return;
} else if (widget.path == '/user') {
Navigator.of(context).pushAndRemoveUntil(UserScreen.route(false), (_) => false);
return;
} else if (widget.path.contains('/user/')) {
Navigator.of(context).pushAndRemoveUntil(UserScreen.routeCode(widget.path.split('/')[2]), (_) => false);
return;
} else if (widget.path == '/about') {
Navigator.of(context).pushAndRemoveUntil(AboutScreen.route(), (_) => false);
return;
} else {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
}
});
}
@override
Widget build(BuildContext context) {
return SizedBox();
}
}
SimpleRoute 的代码是:
class SimpleRoute extends PageRoute {
SimpleRoute({@required String name, @required this.title, @required this.builder, @required this.animated})
: super(settings: RouteSettings(name: name));
final String title;
final WidgetBuilder builder;
final bool animated;
@override
Color get barrierColor => null;
@override
String get barrierLabel => null;
@override
bool get maintainState => true;
@override
Duration get transitionDuration => Duration(milliseconds: 200);
@override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return animated
? FadeTransition(
opacity: animation,
child: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
),
)
: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
);
}
}
所以,最后...如果您想轻松打开其中一个屏幕,您可以这样做:
class HomeScreen extends StatefulWidget {
static Route<dynamic> route(bool animated) {
return SimpleRoute(name: '/', title: 'Home', builder: (_) => HomeScreen(), animated: animated);
}
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
...
}
routeCode 可能是:
static Route<dynamic> routeCode(String id) {
return SimpleRoute(name: '/user/$id', title: 'User', builder: (_) => UserScreen(id: id), animated: false);
}
这样做的主要好处是避免访问最后一个屏幕生成的页面堆栈。
例如,如果您直接使用 onGenerateRoute 表示“www.mywebsite.com/user/userId/edit”,那么 Flutter 将打开:
但使用这种方法,只会打开“编辑屏幕”。