在导航到一个新页面和返回一节中,我们通过创建一个新的路由并将它推到 Navigator
类中学习到了如何导航到新的一个界面 (screen)。
然而,如果我们需要在应用的很多地方导航到同一界面,这样做就会导致代码重复。在这种情况下,定义“命名路由(named route)”并使用它进行导航就会非常方便。
要使用命名路由,我们可以使用 Navigator.pushNamed
方法。下面的例子展示如何使用“命名路由”来实现前一节中的功能。
步骤
创建两个界面
定义路由
使用
Navigator.pushNamed
跳转到第二个界面使用
Navigator.pop
返回到第一个界面
1. 创建两个界面
首先,我们需要两个界面来开始。第一个界面将包含一个跳转到第二个界面的按钮。第二个界面将包含一个跳转回第一个界面的按钮。
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
// 点击时跳转到第二个界面!(Navigate to second screen when tapped!)
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// 点击时跳转回第一个界面!(Navigate back to first screen when tapped!)
},
child: Text('Go back!'),
),
),
);
}
}
2. 定义路由
接下来,我们需要通过为 MaterialApp
的构造函数额外的属性:initialRoute
和 routes
自身,来定义我们的路由。
initialRoute
属性定义了应用应该从哪个路由启动。routes
属性定义了所有可用的命名路由,以及当我们跳转到这些路由时应该构建的 Widgets。
MaterialApp(
// 使用“/”命名路由来启动应用(Start the app with the "/" named route. In our case, the app will start)
// 在这里,应用将从 FirstScreen Widget 启动(on the FirstScreen Widget)
initialRoute: '/',
routes: {
// 当我们跳转到“/”时,构建 FirstScreen Widget(When we navigate to the "/" route, build the FirstScreen Widget)
'/': (context) => FirstScreen(),
// 当我们跳转到“/second”时,构建 SecondScreen Widget(When we navigate to the "/second" route, build the SecondScreen Widget)
'/second': (context) => SecondScreen(),
},
);
注意:当使用 initialRoute
时,需要确保你没有同时定义 home
属性。
3. 跳转到第二个界面
准备好了 Widgets 和路由,我们就可以开始进行页面跳转!在这里,我们将使用 Navigator.pushNamed
函数。它会告诉 Flutter 去构建我们在 routes
表中定义的 Widget 并启动该界面。
在 FirstScreen
Widget 的 build
方法中,我们将更新 onPressed
回调:
// 在 `FirstScreen` Widget中(Within the `FirstScreen` Widget)
onPressed: () {
// 使用命名路由跳转到第二个界面(Navigate to the second screen using a named route)
Navigator.pushNamed(context, '/second');
}
4. 返回到第一个界面
为了能够跳转回第一个页面,我们可以使用 Navigator.pop
方法。
// 在 SecondScreen Widget 中(Within the SecondScreen Widget)
onPressed: () {
// 通过从堆栈弹出当前路由(Navigate back to the first screen by popping the current route)
// 来返回到第一个界面(off the stack)
Navigator.pop(context);
}
完整示例
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Named Routes Demo',
// 使用“/”命名路由来启动应用(Start the app with the "/" named route. In our case, the app will start)
// 在这里,应用将从 FirstScreen Widget 启动(on the FirstScreen Widget)
initialRoute: '/',
routes: {
// 当我们跳转到“/”时,构建 FirstScreen Widget(When we navigate to the "/" route, build the FirstScreen Widget)
'/': (context) => FirstScreen(),
// 当我们跳转到“/second”时,构建 SecondScreen Widget(When we navigate to the "/second" route, build the SecondScreen Widget)
'/second': (context) => SecondScreen(),
},
));
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
// 使用命名路由跳转到第二个界面(Navigate to the second screen using a named route)
Navigator.pushNamed(context, '/second');
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// 通过从堆栈弹出当前路由(Navigate back to the first screen by popping the current route)
// 来返回到第一个界面(off the stack)
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}