Flutter 的路由導航

移動的小太陽發表於2021-04-01

Flutter 的路由導航

路由管理或導航管理:從一個頁面平滑地過渡到另一個頁面,我們需要有一個統一的機制來管理頁面之間的跳轉。在原生的Android 開發,是通過startActivity或startActivityForResult 來完成頁面的跳轉的,在Flutter 中如何實現呢?

在 Flutter 中,頁面之間的跳轉是通過 Route 和 Navigator 來管理的:

  • Route 是頁面的抽象,主要負責建立對應的介面,接收引數,響應 Navigator 開啟和關閉;
  • 而 Navigator 則會維護一個路由棧管理 Route,Route 開啟即入棧,Route 關閉即出棧,還可以直接替換棧內的某一個 Route。

在Flutter 中根據是否提前註冊,可以分為 基本路由和 命名路由。

基本路由:沒有提前註冊。

命名路由:需要在 APP 的入口進行註冊。

基本路由使用方式相對簡單靈活,適用於應用中頁面不多的場景。而在應用中頁面比較多的情況下,再使用基本路由方式,那麼每次跳轉到一個新的頁面,我們都要手動建立 MaterialPageRoute 例項,初始化頁面,然後呼叫 push 方法開啟它,還是比較麻煩的。

應用程式 MaterialApp 提供一個頁面名稱對映規則,即路由表 routes,路由表實際上是一個 Map,其中 key 值對應頁面名字,而 value 值則是一個 WidgetBuilder 回撥函式,我們需要在這個函式中建立對應的頁面。而一旦在路由表中定義好了頁面名字,我們就可以使用 Navigator.pushNamed 來開啟頁面了。

需要注意的是,要在 進入APP入口的 MaterialApp 註冊路由才有用。

使用基本路由方式開啟 Page1:
 Navigator.push(
                context, MaterialPageRoute(builder: (context) => Page1())),
                
 命名路由:
 void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      routes: {
      // 註冊路由
        "route_Page1": (context) => Page1(),
       ...
      },
      onUnknownRoute: (RouteSettings setting) =>
          MaterialPageRoute(builder: (context) => ErrorPage()),
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
// 使用命名路由方式開啟 Page1:
Navigator.pushNamed(context, "route_Page1"),
複製程式碼

預設路由

使用命名路由,該命名不在路由表中就會報錯,這時候可以通過設定預設路由,當找不到的時候,進到到一個指定的頁面。只需要在 MaterialApp 中配置:onUnknownRoute 即可

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      routes: {
        "route_Page1": (context) => Page1(),
        ......
      },
      // 路由發生錯誤,進入到該指定頁面
      onUnknownRoute: (RouteSettings setting) =>
          MaterialPageRoute(builder: (context) => ErrorPage()),
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
複製程式碼

頁面跳轉並傳遞引數

通過 Navigator.pushNamed 傳入 arguments 屬性;然後在開啟的頁面 通過 ModalRoute.of(context).settings.arguments來獲取引數;引數的回傳通過 Navigator.pop 方法

1. 傳遞引數:
 Navigator.pushNamed(context, "route_Page3", arguments: "hello"),
 2. 接收引數:
 
class Page3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String msg = ModalRoute.of(context).settings.arguments as String;
    return Scaffold(
      backgroundColor: Colors.red,
      appBar: AppBar(
        title: Text("傳遞引數"),
      ),
      body: Text("得到的引數是:$msg"),
    );
  }
}
3, 引數的回傳
class Page4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String msg = ModalRoute.of(context).settings.arguments as String;
    return Scaffold(
      backgroundColor: Colors.yellow,
      appBar: AppBar(
        title: Text("返回引數"),
      ),
      body: Text("得到的引數是:$msg"),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.backspace),
        onPressed: () => Navigator.pop(context, "hi"),
      ),
    );
  }
}
4. 回傳引數的接收:通過then方法
 Navigator.pushNamed(context, "route_Page4", arguments: "hello")
                    .then((value) => print("返回的引數是$value")),
複製程式碼

總結

頁面間的跳轉通過 Navigator 和 PageRoute來完成,有兩種方式:基本路由 和命名路由;由於使用命名路由可能存在 路由找不到頁面的情況,所以通過配置 onUnknownRoute 屬性來確定,在路由找不到的時候進入到指定頁面;通過通過介紹頁面跳轉的引數傳遞和介紹,完成了頁面跳轉的介紹。

相關文章