導航到新螢幕並返回
如何實現頁面之間的導航。
大多數應用程式包含多個用於展示不同型別資訊的螢幕。例如,應用可能有一個顯示產品的螢幕。當用戶點選產品圖片時,會跳轉到一個顯示產品詳情的新螢幕。
在 Android 中,一個路由等同於一個 Activity。在 iOS 中,一個路由等同於一個 ViewController。而在 Flutter 中,一個路由僅僅是一個 Widget。
本指南使用 Navigator 來導航到新路由。
接下來的部分將透過以下步驟展示如何在兩個路由之間導航:
- 建立兩個路由。
- 使用
Navigator.push()導航到第二個路由。 - 使用
Navigator.pop()返回第一個路由。
1. 建立兩個路由
#首先,建立兩個用於演示的路由。由於這是一個基礎示例,每個路由僅包含一個按鈕。點選第一個路由上的按鈕將導航到第二個路由。點選第二個路由上的按鈕將返回到第一個路由。
首先,設定可視結構
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!'),
),
),
);
}
}
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: () {
// Navigate to second route when tapped.
},
),
),
);
}
}
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: () {
// Navigate back to first route when tapped.
},
child: const Text('Go back!'),
),
),
);
}
}
2. 使用 Navigator.push() 導航至第二個路由
#要切換到新路由,請使用 Navigator.push() 方法。push() 方法會將一個 Route 新增到 Navigator 管理的路由堆疊中。Route 從何而來?你可以建立自己的路由,也可以使用平臺特定的路由,例如 MaterialPageRoute 或 CupertinoPageRoute。平臺特定的路由非常有用,因為它們會使用符合平臺風格的動畫過渡到新頁面。
在 FirstRoute 元件的 build() 方法中,更新 onPressed() 回撥:
// Within the `FirstRoute` widget:
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const SecondRoute(),
),
);
}
// Within the `FirstRoute` widget:
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute<void>(
builder: (context) => const SecondRoute(),
),
);
}
3. 使用 Navigator.pop() 返回第一個路由
#如何關閉第二個路由並返回到第一個路由?使用 Navigator.pop() 方法即可。pop() 方法會從 Navigator 管理的路由堆疊中移除當前的 Route。
要實現返回到原始路由的功能,請更新 SecondRoute 元件中的 onPressed() 回撥:
// 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<void>(
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!'),
),
),
);
}
}
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<void>(
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!'),
),
),
);
}
}
其他導航方法
#本主題中的指南展示了使用 Navigator 類中的 push 和 pop 方法導航到新螢幕並返回上一級的基本方法,但 Navigator 還有其他幾種靜態方法可以使用。以下是其中一些:
-
pushAndRemoveUntil:將導航路由新增到堆疊,然後移除堆疊中最近的路由,直到滿足特定條件。 -
pushReplacement:用新路由替換堆疊頂部的當前路由。 -
replace:將堆疊上的一個路由替換為另一個路由。 -
replaceRouteBelow:替換堆疊中特定路由下方的路由。 -
popUntil:移除導航路由堆疊中最近新增的路由,直到滿足特定條件。 -
removeRoute:從堆疊中移除特定路由。 -
removeRouteBelow:移除堆疊中特定路由下方的路由。 -
restorablePush:恢復從堆疊中移除的路由。