路由:核心是 路由映射表
.
如:名字detail
映射到 DetailPage
頁(yè)面等
在Flutter中只估,路由管理主要有兩個(gè)類:Route和Navigator.
Route
一個(gè)頁(yè)面要想被路由統(tǒng)一管理,必須包裝為一個(gè)Route
Navigator
管理所有的Route的Widget蛛勉,通過一個(gè)Stack來(lái)進(jìn)行管理.
MaterialApp、CupertinoApp避除、WidgetsApp它們默認(rèn)是有插入Navigator的,在需要的時(shí)候顷霹,只需要直接使用即可.
Navigator.of(context)
Navigator常用方法:
// 路由跳轉(zhuǎn):傳入一個(gè)路由對(duì)象
Future<T> push<T extendsObject>(Route<T> route)
// 路由跳轉(zhuǎn):傳入一個(gè)名稱(命名路由)
Future<T> pushNamed<T extendsObject>(
String routeName, {
Object arguments,
})
// 路由返回:可以傳入一個(gè)參數(shù)
bool pop<T extendsObject>([ T result ])
命名路由
- 命名路由是將名字和路由的映射關(guān)系疲牵,在一個(gè)地方進(jìn)行統(tǒng)一的管理
- 有了命名路由,就可以通過
Navigator.pushNamed()
方法來(lái)跳轉(zhuǎn)到新的頁(yè)面
命名路由的位置
放在MaterialApp的 initialRoute 和 routes 中
initialRoute
:設(shè)置應(yīng)用程序從哪一個(gè)路由開始啟動(dòng)虑椎,設(shè)置了該屬性震鹉,就不需要再設(shè)置home屬性了routes
:定義名稱和路由之間的映射關(guān)系,類型為Map<String, WidgetBuilder>
onGenerateRoute
: 通過pushNamed進(jìn)行跳轉(zhuǎn)捆姜,但是對(duì)應(yīng)的name沒有在routes中有映射關(guān)系传趾,那么就會(huì)執(zhí)行onGenerateRoute
鉤子函數(shù) . 另外,onGenerateRoute
也可以作為頁(yè)面跳轉(zhuǎn)的權(quán)限控制.;onUnknownRoute
: 如果打開的一個(gè)路由名稱是根本不存在的泥技,這個(gè)時(shí)候可以跳轉(zhuǎn)到一個(gè)統(tǒng)一的錯(cuò)誤頁(yè)面浆兰。
打開命名路由時(shí),如果指定的路由名在路由表中已注冊(cè)珊豹,則會(huì)調(diào)用路由表中的builder函數(shù)來(lái)生成路由組件簸呈;如果路由表中沒有注冊(cè),才會(huì)調(diào)用onGenerateRoute來(lái)生成路由店茶。
完整代碼
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue, splashColor: Colors.transparent),
initialRoute: "/",
routes: {
"/": (context) => MyHomePage(title: 'Flutter Demo Home Page'), //注冊(cè)首頁(yè)路由
// "/home": (ctx) => HomePage(),
"/detail": (ctx) => DetailPage()
},
onGenerateRoute: (settings) { //路由鉤子 . 手動(dòng)創(chuàng)建對(duì)應(yīng)的Route進(jìn)行返回蜕便;
if (settings.name == "/about") { //settings.name: 跳轉(zhuǎn)的路徑名稱
return MaterialPageRoute(builder: (ctx) {
return AboutPage(settings.arguments); //settings.arguments:跳轉(zhuǎn)時(shí)攜帶的參數(shù)
});
}
return null;
},
onUnknownRoute: (settings) {
return MaterialPageRoute(builder: (ctx) {
return UnknownPage();
});
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// final message = ModalRoute.of(context).settings.arguments;
var _message = '';
_onPushTop(BuildContext context) {
final future = Navigator.of(context)
.pushNamed('/detail', arguments: "a home message of naned route"); //主動(dòng)跳轉(zhuǎn)時(shí)arguments傳遞參數(shù)
// 2.獲取結(jié)果
future.then((res) {
setState(() {
_message = res;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'顯示結(jié)果: ' + _message,
),
FlatButton(
child: Text("跳轉(zhuǎn)下一頁(yè)", style: TextStyle(color: Colors.black)),
onPressed: () => _onPushTop(context),
),
RaisedButton(
child: Text("打開關(guān)于頁(yè)"),
onPressed: () {
Navigator.of(context).pushNamed(AboutPage.routeName,
arguments: "a home message");
},
),
RaisedButton(
child: Text("打開未知頁(yè)面"),
onPressed: () {
Navigator.of(context).pushNamed("/abc");
},
),
],
),
),
);
}
}
class DetailPage extends StatelessWidget {
// 按鈕點(diǎn)擊執(zhí)行的代碼
_onBackTap(BuildContext context) {
Navigator.of(context).pop("a detail message");
}
@override
Widget build(BuildContext context) {
//接收上級(jí)頁(yè)面?zhèn)鬟^來(lái)的參數(shù)
final message = ModalRoute.of(context).settings.arguments;
return new Scaffold(
appBar: new AppBar(
title: Text('這是第二頁(yè)'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop("a back detail message"); //pop跳轉(zhuǎn)時(shí)直接放入?yún)?shù)
},
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'首頁(yè)帶來(lái)的內(nèi)容: ' + message,
),
// child:
RaisedButton(
child: Text("返回首頁(yè)"),
onPressed: () => _onBackTap(context),
),
]),
),
);
}
}
class AboutPage extends StatelessWidget {
static const String routeName = "/about";
final String message;
AboutPage(this.message);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("關(guān)于頁(yè)面"),
),
body: Center(
child: Text(
message,
style: TextStyle(fontSize: 30, color: Colors.red),
),
),
);
}
}
class UnknownPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("錯(cuò)誤頁(yè)面"),
),
body: Container(
child: Center(
child: Text("頁(yè)面跳轉(zhuǎn)錯(cuò)誤"),
),
),
);
}
}