在导航到一个新页面和返回一节中,我们通过创建一个新的路由并将它推到 Navigator 类中学习到了如何导航到新的一个界面 (screen)。
然而,如果我们需要在应用的很多地方导航到同一界面,这样做就会导致代码重复。在这种情况下,定义“命名路由(named route)”并使用它进行导航就会非常方便。
要使用命名路由,我们可以使用 Navigator.pushNamed 方法。下面的例子展示如何使用“命名路由”来实现前一节中的功能。
步骤
创建两个界面
定义路由
使用
Navigator.pushNamed跳转到第二个界面使用
Navigator.pop返回到第一个界面
1. 创建两个界面
首先,我们需要两个界面来开始。第一个界面将包含一个跳转到第二个界面的按钮。第二个界面将包含一个跳转回第一个界面的按钮。
class FirstScreen extends StatelessWidget {@overrideWidget 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 {@overrideWidget 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 {@overrideWidget 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 {@overrideWidget 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!'),),),);}}
