什么是路由route
1、熟悉前端的朋友知道飒货,這跟web開(kāi)發(fā)中單頁(yè)應(yīng)用的Route概念意義是相同的魄衅;
2、Route在Android中通常指一個(gè)Activity膏斤,在iOS中指一個(gè)ViewController徐绑;
3、路由入棧(push)操作對(duì)應(yīng)打開(kāi)一個(gè)新頁(yè)面莫辨,路由出棧(pop)操作對(duì)應(yīng)頁(yè)面關(guān)閉操作;比如android中就是startActivity和finish毅访;
4沮榜、路由管理主要是指如何來(lái)管理路由棧。
Navigator
Navigator是一個(gè)路由管理的組件喻粹,它提供了打開(kāi)和退出路由頁(yè)方法蟆融。Navigator通過(guò)一個(gè)棧來(lái)管理活動(dòng)路由集合。
常用的兩個(gè)方法:
Future push(BuildContext context, Route route)
將給定的路由入棧(即打開(kāi)新的頁(yè)面)守呜,返回值是一個(gè)Future對(duì)象型酥,用以接收新路由出棧(即關(guān)閉)時(shí)的返回?cái)?shù)據(jù)。
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
bool pop(BuildContext context, [ result ])
將棧頂路由出棧查乒,result為頁(yè)面關(guān)閉時(shí)返回給上一個(gè)頁(yè)面的數(shù)據(jù)弥喉。
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
return Navigator.of(context).pop<T>(result);
}
MaterialPageRoute
MaterialPageRoute 是Material組件庫(kù)提供的組件,它可以針對(duì)不同平臺(tái)玛迄,實(shí)現(xiàn)與平臺(tái)頁(yè)面切換動(dòng)畫(huà)風(fēng)格一致的路由切換動(dòng)畫(huà):
MaterialPageRoute({
@required this.builder, //是一個(gè)WidgetBuilder類(lèi)型的回調(diào)函數(shù)由境,返回新路由的實(shí)例。
RouteSettings settings, //包含路由的配置信息,如路由名稱(chēng)虏杰、是否初始路由(首頁(yè))讥蟆。
this.maintainState = true, //是否釋放所占用的所有資源
bool fullscreenDialog = false, //新的路由頁(yè)面是否是一個(gè)全屏的模態(tài)對(duì)話框
})
Navigator+MaterialPageRoute
點(diǎn)擊關(guān)于跳轉(zhuǎn)到About頁(yè)面
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => (About())));
}
命名路由
所謂“命名路由”(Named Route)即有名字的路由,我們可以先給路由起一個(gè)名字纺阔,然后就可以通過(guò)路由名字直接打開(kāi)新的路由了瘸彤,這為路由管理帶來(lái)了一種直觀、簡(jiǎn)單的方式笛钝。
注冊(cè)路由表
Map<String, WidgetBuilder> routes;
它是一個(gè)Map质况,key為路由的名字,是個(gè)字符串婆翔;value是個(gè)builder回調(diào)函數(shù)拯杠,用于生成相應(yīng)的路由widget。我們?cè)谕ㄟ^(guò)路由名字打開(kāi)新路由時(shí)啃奴,應(yīng)用會(huì)根據(jù)路由名字在路由表中查找到對(duì)應(yīng)的WidgetBuilder回調(diào)函數(shù)潭陪,然后調(diào)用該回調(diào)函數(shù)生成路由widget并返回。
可以理解成
www.xxx.com/ 進(jìn)入首頁(yè)
www.xxx.com/about 進(jìn)入關(guān)于我們頁(yè)面
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: "/",
theme: ThemeData(primarySwatch: Colors.green, primaryColor: Colors.white),//設(shè)置App主題
routes: {
"/":(context)=>MyHomePage(),
"/about":(context)=>About()
},
);
}
}
通過(guò)路由名打開(kāi)新路由頁(yè)
@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
BuildContext context, //上下文
String routeName, { //路由名
Object arguments, //頁(yè)面?zhèn)鲄? }) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}
通過(guò)routeName跳轉(zhuǎn)
onTap: () {
Navigator.pushNamed(context, "/about");
//Navigator.push(context, MaterialPageRoute(builder: (context) => (About())));
},
路由參數(shù)傳遞
普通push傳遞參數(shù)
class OtherGank extends StatelessWidget {
final String content;
OtherGank({Key key, this.content}) : super(key: key);
@override
Widget build(BuildContext context) {
var args=ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text("其他Gank項(xiàng)目"),
),
body: Center(child: Text(args==null?content:args)),
);
}
}
Navigator.push(context, MaterialPageRoute(builder: (context) => (OtherGank(content: "這是route傳遞的參數(shù)",))));
命名路由參數(shù)傳遞
傳遞
Navigator.pushNamed(context, "/other",arguments: "這是route傳遞的參數(shù)");
接收
var args=ModalRoute.of(context).settings.arguments;
路由返回值
接收返回參數(shù)
onTap: () async {
var res = await Navigator.pushNamed(context, "/other",arguments: "這是route傳遞的參數(shù)");
LogUtils.log(res);
},
傳遞返回參數(shù)
body: Center(child: RaisedButton(
onPressed: (){
Navigator.pop(context,"我要帶返回值回去~");
},
child: Text("帶參數(shù)回去"),
)),
點(diǎn)擊button返回的就是帶了參數(shù)的最蕾,點(diǎn)擊AppBar的返回按鈕則為null依溯。也就是說(shuō)點(diǎn)擊AppBar的返回按鈕執(zhí)行的是
Navigator.pop(context)
路由鉤子
當(dāng)使用命名路由跳轉(zhuǎn)時(shí)在跳轉(zhuǎn)之前可以做統(tǒng)一的登錄判斷權(quán)限判斷之類(lèi)的事情。
MaterialApp(
... //省略無(wú)關(guān)代碼
onGenerateRoute:(RouteSettings settings){
return MaterialPageRoute(builder: (context){
String routeName = settings.name;
// 如果訪問(wèn)的路由頁(yè)需要登錄瘟则,但當(dāng)前未登錄黎炉,則直接返回登錄頁(yè)路由,
// 引導(dǎo)用戶(hù)登錄醋拧;其它情況則正常打開(kāi)路由慷嗜。
}
);
}
);
- 注意,onGenerateRoute只會(huì)對(duì)命名路由生效丹壕。
更詳細(xì)的資料
完整代碼
https://github.com/leiyun1993/FlutterDemo-GankIO
ps:以上完整代碼為Demo代碼庆械。本文中的代碼只為了測(cè)試路由功能,可能在項(xiàng)目中無(wú)法找到完全一樣的代碼菌赖!