跳至主要内容

导航到新屏幕并返回

大多数应用包含多个屏幕来显示不同类型的信息。例如,一个应用可能有一个显示产品的屏幕。当用户点击产品图片时,一个新的屏幕会显示有关该产品的详细信息。

在 Android 中,路由等效于 Activity。在 iOS 中,路由等效于 ViewController。在 Flutter 中,路由只是一个 widget。

本食谱使用 Navigator 导航到新的路由。

接下来的几个部分将展示如何使用以下步骤在两个路由之间导航

  1. 创建两个路由。
  2. 使用 Navigator.push() 导航到第二个路由。
  3. 使用 Navigator.pop() 返回到第一个路由。

1. 创建两个路由

#

首先,创建两个要使用的路由。由于这是一个基本示例,因此每个路由仅包含一个按钮。点击第一个路由上的按钮会导航到第二个路由。点击第二个路由上的按钮会返回到第一个路由。

首先,设置视觉结构

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

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

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

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

2. 使用 Navigator.push() 导航到第二个路由

#

要切换到新的路由,请使用 Navigator.push() 方法。push() 方法将一个 Route 添加到由 Navigator 管理的路由堆栈中。Route 来自哪里?您可以创建自己的路由,或者使用 MaterialPageRoute,它很有用,因为它使用特定于平台的动画过渡到新路由。

FirstRoute widget 的 build() 方法中,更新 onPressed() 回调

dart
// Within the `FirstRoute` widget:
onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => const SecondRoute()),
  );
}

3. 使用 Navigator.pop() 返回到第一个路由

#

如何关闭第二个路由并返回到第一个路由?通过使用 Navigator.pop() 方法。pop() 方法从由 Navigator 管理的路由堆栈中移除当前的 Route

要实现返回到原始路由,请更新 SecondRoute widget 中的 onPressed() 回调

dart
// Within the SecondRoute widget
onPressed: () {
  Navigator.pop(context);
}

交互式示例

#
import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Route'),
      ),
      body: Center(
        child: ElevatedButton(
          child: const Text('Open route'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const SecondRoute()),
            );
          },
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Route'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}
#

在前面的示例中,您学习了如何使用来自 Material 组件MaterialPageRoute 在屏幕之间导航。但是,在 Flutter 中,您不限于 Material 设计语言,还可以访问 Cupertino(iOS 风格)widget。

使用 Cupertino widget 实现导航的步骤与使用 MaterialPageRoute 相同,但您使用的是 CupertinoPageRoute,它提供了 iOS 风格的过渡动画。

在以下示例中,这些 widget 已被替换

这样,示例遵循当前的 iOS 设计语言。

import 'package:flutter/cupertino.dart';

void main() {
  runApp(const CupertinoApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

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

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('First Route'),
      ),
      child: Center(
        child: CupertinoButton(
          child: const Text('Open route'),
          onPressed: () {
            Navigator.push(
              context,
              CupertinoPageRoute(builder: (context) => const SecondRoute()),
            );
          },
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('Second Route'),
      ),
      child: Center(
        child: CupertinoButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}