導向到對應名稱的 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.
  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
onPressed: () {
  // Navigate to the second screen using a named route.
  Navigator.pushNamed(context, '/second');
}

4. 回傳到第一個介面

為了能夠跳轉回第一個頁面,我們可以使用 Navigator.pop() 方法。

// Within the SecondScreen widget
onPressed: () {
  // 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.
            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.
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}