1. 程式人生 > 其它 >【Flutter 3-1】Flutter進階教程——路由Router和導航Navigator以及傳值

【Flutter 3-1】Flutter進階教程——路由Router和導航Navigator以及傳值

技術標籤:Flutterflutterflutter教程flutter自學flutter路由flutter導航

作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)

路由

在移動開發中,我們管頁面之間的跳轉叫做路由。在iOS中指的就是ViewController之間的跳轉,在Android中就是Activity之間的跳轉。路由是在移動端開發中非常重要的概念,它負責管理著各個頁面之間的跳轉還有傳值工作,是必不可缺少的控制元件。

路由Map

為了方便我們管理跳轉頁面,Flutter為我們 提供了路由Map。
路由Map由在main.dart檔案裡面MaterialApp的引數routes

管理,routes引數接收一個Map,Map裡面就是我們專案的路由Map,你可以開啟我的專案看到routes引數如下:

routes: {
  "/": (context) => MainPage(),
  "TextDemoPage": (context) => TextDemoPage(),
  "RaisedButtonDemoPage": (context) => RaisedButtonDemoPage(),
  "FlatButtonDemoPage": (context) => FlatButtonDemoPage(),
  "OutlineButtonDemoePage": (context) => OutlineButtonDemoePage(),
  "IconButtonDemoPage": (context) => IconButtonDemoPage(),
  "ContainerDemoPage": (context) => ContainerDemoPage(),
  "StatefulWidgetDemoPage": (context) => StatefulWidgetDemoPage(),
  "TextFieldDemoPage": (context) => TextFieldDemoPage(),
  "ImageDemoPage": (context) => ImageDemoPage(),
  "ColumnDemoPage": (context) => ColumnDemoPage(),
  "RowDemoPage": (context) => RowDemoPage(),
  "FlexibleDemoPage": (context) => FlexibleDemoPage(),
  "WrapDemoPage": (context) => WrapDemoPage(),
  "ListViewDemoPage": (context) => ListViewDemoPage(),
  "GridViewDemoPage": (context) => GridViewDemoPage(),
  "BottomNavigationBarDemoPage": (context) =>
      BottomNavigationBarDemoPage(),
  "RouterDemoPage": (context) => RouterDemoPage(),
  "RouterDemoPage2": (context) => RouterDemoPage2(),
},

其中key/對應的Value是整個Flutter專案的入口頁面,這裡需要另外一個很重要的引數initialRoute來配合使用
我們給initialRoute引數傳值如下:

    initialRoute: "/",

這裡表示的是Flutter專案的入口頁面對應的key/,那麼就會找到在routes/對應的頁面,也就是MainPage()

需要注意的是:
預設我們新建立的Flutter專案中MaterialApp是帶有home這個引數的,它也表示也是入口頁面。如果我們想要要使用路由Map的方式來管理路由,一定需要把home引數刪除掉。

Navigator.pushNamed

在我們宣告好路由Map之後,我們就可以傳入前面的key的值來實現頁面的跳轉工作,這個時候我們需要藉助的API是Navigator.pushNamed

 @optionalTypeArgs
  static Future<T> pushNamed<T extends Object>(
    BuildContext context,    /// context
    String routeName, {     /// 路由Map中 key 的值
    Object arguments,        /// 引數
   }) {
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

只需要傳入路由Map中key的值就可以實現跳轉。
程式碼如下:

Navigator.pushNamed(context, "RouterDemoPage2");

由於我們是跨平臺開發,Flutter幫助我們實現了跳轉時候的轉場動畫,在iOS中動畫是從右側滑入到左側,返回的時候同樣是由左側滑出到右側。在Android則是由下方彈出顯示到上方,返回的時候是由上方退出到下方彈出。

跳轉傳值

很多時候我們希望跳轉的時候可以傳值過去,這個時候我們可以通過自定義MaterialPageRoute來實現傳值。

MaterialPageRoute({
    /// builder 方法
    @required this.builder,
    /// 配置資訊
    RouteSettings settings,
    ///  預設情況下,當入棧一個新路由時,原來的路由仍然會被儲存在記憶體中,如果想在路由沒用的時候釋放其所佔用的所有資源,可以設定maintainState為false。
    this.maintainState = true,
    ///  表示新頁面是否是全屏展示,在iOS中,如果fullscreenDialog為true,新頁面將會從螢幕底部滑入
    bool fullscreenDialog = false,
})

我們只需要在構建新的頁面的時候傳入我們想要傳遞的引數即可

Navigator.of(context).push(MaterialPageRoute(builder: (context) {
  return RouterDemoPage3(passText: "Fulade");
}));

返回傳值

傳遞返回值我們使用Navigatorpop方法即可

Navigator.pop(context, "pop value");

pop方法接收一個引數為返回的攜帶的引數,如果我們有多個引數,可以把它封裝為ListMap即可。

返回值我們需要在push方法後面使用then來接收

Navigator.of(context)
    .push(MaterialPageRoute(builder: (context) {
  return RouterDemoPage3(passText: "Fulade");
})).then((value) {
  setState(() {
    title = value;
  });
});

then函式 涉及到了Dart語音中很重要的概念 await 和future,後面有機會我們再來詳細的說。

想體驗以上的示例的執行效果,可以到我的Github倉庫專案flutter_app->lib->routes->router_page.dart檢視,並且可以下載下來執行並體驗。


公眾號