所謂路由管理,就是管理頁面之間如何跳轉,通常也可被稱爲導航管理。Flutter中的路由管理和原生開發類似,無論是Android還是iOS,導航管理都會維護一個路由棧,路由入棧(push)操作對應打開一個新頁面,路由出棧(pop)操作對應頁面關閉操作,而路由管理主要是指如何來管理路由棧。
簡單示例
class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New route"),
),
body: Center(
child: Text("This is new route"),
),
);
}
}
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
... //省略無關代碼
FlatButton(
child: Text("open new route"),
textColor: Colors.blue,
onPressed: () {
//導航到新路由
Navigator.push( context,
MaterialPageRoute(builder: (context) {
return NewRoute();
}));
},
),
],
)
- 對於Android,當打開新頁面時,新的頁面會從屏幕底部滑動到屏幕頂部;當關閉頁面時,當前頁面會從屏幕頂部滑動到屏幕底部後消失,同時上一個頁面會顯示到屏幕上。
- 對於iOS,當打開頁面時,新的頁面會從屏幕右側邊緣一致滑動到屏幕左邊,直到新頁面全部顯示到屏幕上,而上一個頁面則會從當前屏幕滑動到屏幕左側而消失;當關閉頁面時,正好相反,當前頁面會從屏幕右側滑出,同時上一個頁面會從屏幕左側滑入。
Navigator
- Future push(BuildContext context, Route route)
將給定的路由入棧(即打開新的頁面),返回值是一個Future
對象,用以接收新路由出棧(即關閉)時的返回數據。
- bool pop(BuildContext context, [ result ])
將棧頂路由出棧,result
爲頁面關閉時返回給上一個頁面的數據。
Navigator類中第一個參數爲context的靜態方法都對應一個Navigator的實例方法:
比如Navigator.push(BuildContext context, Route route)
等價於Navigator.of(context).push(Route route)
路由傳值
class TipRoute extends StatelessWidget {
TipRoute({
Key key,
@required this.text, // 接收一個text參數
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("提示"),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: <Widget>[
Text(text),
RaisedButton(
onPressed: () => Navigator.pop(context, "我是返回值"),
child: Text("返回"),
)
],
),
),
),
);
}
}
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () async {
// 打開`TipRoute`,並等待返回結果
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由參數
text: "我是提示xxxx",
);
},
),
);
//輸出`TipRoute`路由返回結果
print("路由返回值: $result");
},
child: Text("打開提示頁"),
),
);
}
}
命名路由
註冊路由表就是給路由起名字,路由表的定義如下:
Map<String, WidgetBuilder> routes;
- 註冊路由表
MaterialApp(
title: 'Flutter Demo',
initialRoute:"/", //名爲"/"的路由作爲應用的home(首頁)
theme: ThemeData(
primarySwatch: Colors.blue,
),
//註冊路由表
routes:{
"new_page":(context)=>NewRoute(),
"/":(context)=> MyHomePage(title: 'Flutter Demo Home Page'), //註冊首頁路由
}
);
- 通過路由名打開新路由頁
Future pushNamed(BuildContext context, String routeName,{Object arguments})
onPressed: () {
Navigator.pushNamed(context, "new_page");
//Navigator.push(context,
// new MaterialPageRoute(builder: (context) {
// return new NewRoute();
//}));
},
路由器生成鉤子