导航到对应名称的 routes 里

导航到一个新页面和返回 一节中,我们通过创建一个新的路由并将它推到 Navigator 类中学习到了如何导航到新的一个界面 (screen)。

然而,如果我们需要在应用的很多地方导航到同一界面,这样做就会导致代码重复。在这种情况下,定义 命名路由 (named route) 并使用它进行导航就会非常方便。

要使用命名路由,我们可以使用 Navigator.pushNamed() 方法。下面的例子展示如何使用“命名路由”来实现前一节中的功能。

步骤

  1. 创建两个界面

  2. 定义路由

  3. 使用 Navigator.pushNamed() 跳转到第二个界面

  4. 使用 Navigator.pop() 返回到第一个界面

1. 创建两个界面

首先,我们需要两个界面来开始。第一个界面将包含一个跳转到第二个界面的按钮,第二个界面将包含一个跳转回第一个界面的按钮。

import 'package:flutter/material.dart';

class FirstScreen extends StatelessWidget {
  const FirstScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Navigate to the second screen when tapped.
          },
          child: const Text('Launch screen'),
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  const SecondScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Navigate back to first screen when tapped.
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}

2. 定义路由

接下来,我们需要通过为 MaterialApp 的构造函数额外的属性: initialRouteroutes 来定义我们的路由。

initialRoute 属性定义了应用应该从哪个路由启动。 routes 属性定义了所有可用的命名路由,以及当我们跳转到这些路由时应该构建的 widgets。

MaterialApp(
  title: 'Named Routes Demo',
  // Start the app with the "/" named route. In this case, the app starts
  // on the FirstScreen widget.
  
  // 使用“/”命名路由来启动应用(Start the app with the "/" named route. In our case, the app will start)
  // 在这里,应用将从 FirstScreen Widget 启动(on the FirstScreen Widget)
  
  initialRoute: '/',
  routes: {
    // When navigating to the "/" route, build the FirstScreen widget.
    '/': (context) => const FirstScreen(),
    // When navigating to the "/second" route, build the SecondScreen widget.
    '/second': (context) => const SecondScreen(),
  },
)

3. 跳转到第二个界面

准备好了 Widgets 和路由,我们就可以开始进行页面跳转。在这里,我们将使用 Navigator.pushNamed() 函数。它会告诉 Flutter 去构建我们在 routes 表中定义的 widget 并启动该界面。

FirstScreen widget 的 build() 方法中,我们将更新 onPressed() 回调:

// Within the `FirstScreen` widget
// 在 `FirstScreen` Widget中(Within the `FirstScreen` Widget)
onPressed: () {
  // Navigate to the second screen using a named route.
  // 使用命名路由跳转到第二个界面(Navigate to the second screen using a named route)
  Navigator.pushNamed(context, '/second');
}

4. 返回到第一个界面

为了能够跳转回第一个页面,我们可以使用 Navigator.pop() 方法。

// Within the SecondScreen widget
// 在 SecondScreen Widget 中(Within the SecondScreen Widget)
onPressed: () {
  // Navigate back to the first screen by popping the current route
  // off the stack.
  
  // 通过从堆栈弹出当前路由(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 this case, the app starts
      // on the FirstScreen widget.
      initialRoute: '/',
      routes: {
        // When navigating to the "/" route, build the FirstScreen widget.
        '/': (context) => const FirstScreen(),
        // When navigating to the "/second" route, build the SecondScreen widget.
        '/second': (context) => const SecondScreen(),
      },
    ),
  );
}

class FirstScreen extends StatelessWidget {
  const FirstScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          // Within the `FirstScreen` widget
          onPressed: () {
            // Navigate to the second screen using a named route.
            // 使用命名路由跳转到第二个界面(Navigate to the second screen using a named route)
            Navigator.pushNamed(context, '/second');
          },
          child: const Text('Launch screen'),
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  const SecondScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          // Within the SecondScreen widget
          onPressed: () {
            // Navigate back to the first screen by popping the current route
            // off the stack.
            // 通过从堆栈弹出当前路由(Navigate back to the first screen by popping the current route)
            // 来返回到第一个界面(off the stack)
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}