导航到新屏幕并返回

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

在 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 从哪里来?您可以创建自己的 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!'),
        ),
      ),
    );
  }
}
#

在前面的示例中,您学习了如何使用 MaterialPageRouteMaterial Components 在屏幕之间导航。但是,在 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!'),
        ),
      ),
    );
  }
}