作者 | 弗拉德
來源 | 弗拉德(公眾號(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");
}));
返回傳值
傳遞返回值我們使用Navigator的pop方法即可
Navigator.pop(context, "pop value");
pop方法接收一個(gè)參數(shù)為返回的攜帶的參數(shù),如果我們有多個(gè)參數(shù),可以把它封裝為List或Map即可。
返回值我們需要在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)。