我们通常会用“屏”来表示应用的不同页面(界面),比如,某个应用有一“屏”展示商品列表,当用户点击某个商品的图片,会跳到新的一“屏”展示商品的详细信息。

术语: 在 Flutter 中,屏 (screen)页面 (page) 都叫做 路由 (route), 在下文中统称为“路由 (route)”。

在 Android 开发中,Activity 相当于“路由” , 在 iOS 开发中,ViewController 相当于“路由”。在 Flutter 中,“路由”也是一个 Widget。

怎么样从一个“路由”跳转到新的“路由“呢?你需要使用 Navigator 类。

步骤

下面来展示如何在两个路由间跳转,总共分三步:

  • 创建两个路由

  • 用 Navigator.push() 跳转到第二个路由

  • 用 Navigator.pop() 回退到第一个路由

1. 创建两个路由

首先,我们来创建两个路由。这是个最简单的例子,每个路由只包含一个按钮。点击第一个路由上的按钮会跳转到第二个路由,点击第二个路由上的按钮,会回退到第一个路由。

首先来编写界面布局代码:

  1. class FirstRoute extends StatelessWidget {
  2. @override
  3. Widget build(BuildContext context) {
  4. return Scaffold(
  5. appBar: AppBar(
  6. title: Text('First Route'),
  7. ),
  8. body: Center(
  9. child: RaisedButton(
  10. child: Text('Open route'),
  11. onPressed: () {
  12. // Navigate to second route when tapped.
  13. },
  14. ),
  15. ),
  16. );
  17. }
  18. }
  19. class SecondRoute extends StatelessWidget {
  20. @override
  21. Widget build(BuildContext context) {
  22. return Scaffold(
  23. appBar: AppBar(
  24. title: Text("Second Route"),
  25. ),
  26. body: Center(
  27. child: RaisedButton(
  28. onPressed: () {
  29. // Navigate back to first route when tapped.
  30. },
  31. child: Text('Go back!'),
  32. ),
  33. ),
  34. );
  35. }
  36. }

2. 用 Navigator.push() 跳转到第二个路由

使用 Navigator.push()方法跳转到新的路由。push() 方法会添加一个 Route 对象到导航器的堆栈上。 那么这个 Route 对象是从哪里来的呢?你可以自己实现一个,或者直接使用 MaterialPageRoute类。使用 MaterialPageRoute 是非常方便的,框架已经为我们实现了和平台原生类似的切换动画。

FirstRoute widget 的 build() 方法中,我们来修改 onPressed() 回调函数:

  1. // 位于 FirstRoute widget (Within the `FirstRoute` widget)
  2. onPressed: () {
  3. Navigator.push(
  4. context,
  5. MaterialPageRoute(builder: (context) => SecondRoute()),
  6. );
  7. }

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

怎么关闭第二个路由回退到第一个呢? 使用Navigator.pop()方法,pop() 方法会从导航器堆栈上移除 Route 对象。

我们来修改 SecondRoute widget 的 onPressed() 回调函数,实现返回第一个路由的功能:

  1. // 位于 SecondRoute widget (Within the SecondRoute widget)
  2. onPressed: () {
  3. Navigator.pop(context);
  4. }

完整的例子

  1. import 'package:flutter/material.dart';
  2. void main() {
  3. runApp(MaterialApp(
  4. title: 'Navigation Basics',
  5. home: FirstRoute(),
  6. ));
  7. }
  8. class FirstRoute extends StatelessWidget {
  9. @override
  10. Widget build(BuildContext context) {
  11. return Scaffold(
  12. appBar: AppBar(
  13. title: Text('First Route'),
  14. ),
  15. body: Center(
  16. child: RaisedButton(
  17. child: Text('Open route'),
  18. onPressed: () {
  19. Navigator.push(
  20. context,
  21. MaterialPageRoute(builder: (context) => SecondRoute()),
  22. );
  23. },
  24. ),
  25. ),
  26. );
  27. }
  28. }
  29. class SecondRoute extends StatelessWidget {
  30. @override
  31. Widget build(BuildContext context) {
  32. return Scaffold(
  33. appBar: AppBar(
  34. title: Text("Second Route"),
  35. ),
  36. body: Center(
  37. child: RaisedButton(
  38. onPressed: () {
  39. Navigator.pop(context);
  40. },
  41. child: Text('Go back!'),
  42. ),
  43. ),
  44. );
  45. }
  46. }

Navigation Basics Demo