【Flutter 3-2】Flutter進(jìn)階教程——路由Router和導(dǎo)航Navigator以及傳值

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

路由

在移動(dòng)開發(fā)中,我們管頁面之間的跳轉(zhuǎn)叫做路由。在iOS中指的就是ViewController之間的跳轉(zhuǎn),在Android中就是Activity之間的跳轉(zhuǎn)。路由是在移動(dòng)端開發(fā)中非常重要的概念,它負(fù)責(zé)管理著各個(gè)頁面之間的跳轉(zhuǎn)還有傳值工作,是必不可缺少的控件。

路由Map

為了方便我們管理跳轉(zhuǎn)頁面,Flutter為我們 提供了路由Map。
路由Map由在main.dart文件里面MaterialApp的參數(shù)routes管理,routes參數(shù)接收一個(gè)Map,Map里面就是我們項(xiàng)目的路由Map,你可以打開我的項(xiàng)目看到routes參數(shù)如下:

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/對應(yīng)的Value是整個(gè)Flutter項(xiàng)目的入口頁面,這里需要另外一個(gè)很重要的參數(shù)initialRoute來配合使用
我們給initialRoute參數(shù)傳值如下:

    initialRoute: "/",

這里表示的是Flutter項(xiàng)目的入口頁面對應(yīng)的key/,那么就會(huì)找到在routes/對應(yīng)的頁面,也就是MainPage()

需要注意的是:
默認(rèn)我們新創(chuàng)建的Flutter項(xiàng)目中MaterialApp是帶有home這個(gè)參數(shù)的,它也表示也是入口頁面。如果我們想要要使用路由Map的方式來管理路由,一定需要把home參數(shù)刪除掉。

Navigator.pushNamed

在我們聲明好路由Map之后,我們就可以傳入前面的key的值來實(shí)現(xiàn)頁面的跳轉(zhuǎn)工作,這個(gè)時(shí)候我們需要借助的API是Navigator.pushNamed

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

只需要傳入路由Map中key的值就可以實(shí)現(xiàn)跳轉(zhuǎn)。
代碼如下:

Navigator.pushNamed(context, "RouterDemoPage2");

由于我們是跨平臺(tái)開發(fā),F(xiàn)lutter幫助我們實(shí)現(xiàn)了跳轉(zhuǎn)時(shí)候的轉(zhuǎn)場動(dòng)畫,在iOS中動(dòng)畫是從右側(cè)滑入到左側(cè),返回的時(shí)候同樣是由左側(cè)滑出到右側(cè)。在Android則是由下方彈出顯示到上方,返回的時(shí)候是由上方退出到下方彈出。

跳轉(zhuǎn)傳值

很多時(shí)候我們希望跳轉(zhuǎn)的時(shí)候可以傳值過去,這個(gè)時(shí)候我們可以通過自定義MaterialPageRoute來實(shí)現(xiàn)傳值。

MaterialPageRoute({
    /// builder 方法
    @required this.builder,
    /// 配置信息
    RouteSettings settings,
    ///  默認(rèn)情況下,當(dāng)入棧一個(gè)新路由時(shí),原來的路由仍然會(huì)被保存在內(nèi)存中,如果想在路由沒用的時(shí)候釋放其所占用的所有資源,可以設(shè)置maintainState為false。
    this.maintainState = true,
    ///  表示新頁面是否是全屏展示,在iOS中,如果fullscreenDialog為true,新頁面將會(huì)從屏幕底部滑入
    bool fullscreenDialog = false,
})

我們只需要在構(gòu)建新的頁面的時(shí)候傳入我們想要傳遞的參數(shù)即可

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

返回傳值

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

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

pop方法接收一個(gè)參數(shù)為返回的攜帶的參數(shù),如果我們有多個(gè)參數(shù),可以把它封裝為ListMap即可。

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

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

then函數(shù) 涉及到了Dart語音中很重要的概念 await 和future,后面有機(jī)會(huì)我們再來詳細(xì)的說。

想體驗(yàn)以上的示例的運(yùn)行效果,可以到我的Github倉庫項(xiàng)目flutter_app->lib->routes->router_page.dart查看,并且可以下載下來運(yùn)行并體驗(yàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容