詳解Flutter的路由導(dǎo)航
Flutter 的路由導(dǎo)航
路由管理或?qū)Ш焦芾恚簭囊粋€(gè)頁(yè)面平滑地過(guò)渡到另一個(gè)頁(yè)面,我們需要有一個(gè)統(tǒng)一的機(jī)制來(lái)管理頁(yè)面之間的跳轉(zhuǎn)。在原生的Android 開(kāi)發(fā),是通過(guò)startActivity或startActivityForResult 來(lái)完成頁(yè)面的跳轉(zhuǎn)的,在Flutter 中如何實(shí)現(xiàn)呢?
在 Flutter 中,頁(yè)面之間的跳轉(zhuǎn)是通過(guò) Route 和 Navigator 來(lái)管理的:
- Route 是頁(yè)面的抽象,主要負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的界面,接收參數(shù),響應(yīng) Navigator 打開(kāi)和關(guān)閉;
- 而 Navigator 則會(huì)維護(hù)一個(gè)路由棧管理 Route,Route 打開(kāi)即入棧,Route 關(guān)閉即出棧,還可以直接替換棧內(nèi)的某一個(gè) Route。
在Flutter 中根據(jù)是否提前注冊(cè),可以分為 基本路由和 命名路由。
基本路由:沒(méi)有提前注冊(cè)。
命名路由:需要在 APP 的入口進(jìn)行注冊(cè)。
基本路由使用方式相對(duì)簡(jiǎn)單靈活,適用于應(yīng)用中頁(yè)面不多的場(chǎng)景。而在應(yīng)用中頁(yè)面比較多的情況下,再使用基本路由方式,那么每次跳轉(zhuǎn)到一個(gè)新的頁(yè)面,我們都要手動(dòng)創(chuàng)建 MaterialPageRoute 實(shí)例,初始化頁(yè)面,然后調(diào)用 push 方法打開(kāi)它,還是比較麻煩的。
應(yīng)用程序 MaterialApp 提供一個(gè)頁(yè)面名稱(chēng)映射規(guī)則,即路由表 routes,路由表實(shí)際上是一個(gè) Map,其中 key 值對(duì)應(yīng)頁(yè)面名字,而 value 值則是一個(gè) WidgetBuilder 回調(diào)函數(shù),我們需要在這個(gè)函數(shù)中創(chuàng)建對(duì)應(yīng)的頁(yè)面。而一旦在路由表中定義好了頁(yè)面名字,我們就可以使用 Navigator.pushNamed 來(lái)打開(kāi)頁(yè)面了。
需要注意的是,要在 進(jìn)入APP入口的 MaterialApp 注冊(cè)路由才有用。
使用基本路由方式打開(kāi) Page1: Navigator.push( context, MaterialPageRoute(builder: (context) => Page1())), 命名路由: 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', routes: { // 注冊(cè)路由 "route_Page1": (context) => Page1(), ... }, onUnknownRoute: (RouteSettings setting) => MaterialPageRoute(builder: (context) => ErrorPage()), theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } // 使用命名路由方式打開(kāi) Page1: Navigator.pushNamed(context, "route_Page1"),
默認(rèn)路由
使用命名路由,該命名不在路由表中就會(huì)報(bào)錯(cuò),這時(shí)候可以通過(guò)設(shè)置默認(rèn)路由,當(dāng)找不到的時(shí)候,進(jìn)到到一個(gè)指定的頁(yè)面。只需要在 MaterialApp 中配置:onUnknownRoute 即可
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', routes: { "route_Page1": (context) => Page1(), ...... }, // 路由發(fā)生錯(cuò)誤,進(jìn)入到該指定頁(yè)面 onUnknownRoute: (RouteSettings setting) => MaterialPageRoute(builder: (context) => ErrorPage()), theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
頁(yè)面跳轉(zhuǎn)并傳遞參數(shù)
通過(guò) Navigator.pushNamed 傳入 arguments 屬性;然后在打開(kāi)的頁(yè)面 通過(guò) ModalRoute.of(context).settings.arguments來(lái)獲取參數(shù);參數(shù)的回傳通過(guò) Navigator.pop 方法
1. 傳遞參數(shù): Navigator.pushNamed(context, "route_Page3", arguments: "hello"), 2. 接收參數(shù): class Page3 extends StatelessWidget { @override Widget build(BuildContext context) { String msg = ModalRoute.of(context).settings.arguments as String; return Scaffold( backgroundColor: Colors.red, appBar: AppBar( title: Text("傳遞參數(shù)"), ), body: Text("得到的參數(shù)是:$msg"), ); } } 3, 參數(shù)的回傳 class Page4 extends StatelessWidget { @override Widget build(BuildContext context) { String msg = ModalRoute.of(context).settings.arguments as String; return Scaffold( backgroundColor: Colors.yellow, appBar: AppBar( title: Text("返回參數(shù)"), ), body: Text("得到的參數(shù)是:$msg"), floatingActionButton: FloatingActionButton( child: Icon(Icons.backspace), onPressed: () => Navigator.pop(context, "hi"), ), ); } } 4. 回傳參數(shù)的接收:通過(guò)then方法 Navigator.pushNamed(context, "route_Page4", arguments: "hello") .then((value) => print("返回的參數(shù)是$value")),
總結(jié)
頁(yè)面間的跳轉(zhuǎn)通過(guò) Navigator 和 PageRoute來(lái)完成,有兩種方式:基本路由 和命名路由;由于使用命名路由可能存在 路由找不到頁(yè)面的情況,所以通過(guò)配置 onUnknownRoute 屬性來(lái)確定,在路由找不到的時(shí)候進(jìn)入到指定頁(yè)面;通過(guò)通過(guò)介紹頁(yè)面跳轉(zhuǎn)的參數(shù)傳遞和介紹,完成了頁(yè)面跳轉(zhuǎn)的介紹。
以上就是詳解Flutter的路由導(dǎo)航的詳細(xì)內(nèi)容,更多關(guān)于Flutter 路由導(dǎo)航的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解升級(jí)Android Studio3.0時(shí)遇到的幾個(gè)問(wèn)題
本篇文章主要介紹了升級(jí)Android Studio3.0時(shí)遇到的幾個(gè)問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10Android編程實(shí)現(xiàn)為應(yīng)用添加菜單的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)為應(yīng)用添加菜單的方法,涉及Android菜單界面布局與功能實(shí)現(xiàn)的相關(guān)技巧,需要的朋友可以參考下2016-01-01Android 開(kāi)機(jī)直接運(yùn)行app并當(dāng)做手機(jī)桌面的實(shí)例
今天小編就為大家分享一篇Android 開(kāi)機(jī)直接運(yùn)行app并當(dāng)做手機(jī)桌面的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-085分鐘學(xué)會(huì)Android設(shè)計(jì)模式之策略模式Strategy Pattern教程
這篇文章主要為大家介紹了5分鐘學(xué)會(huì)Android設(shè)計(jì)模式之策略模式Strategy Pattern教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android中使用七牛云存儲(chǔ)進(jìn)行圖片上傳下載的實(shí)例代碼
這篇文章主要介紹了Android中使用七牛云存儲(chǔ)進(jìn)行圖片上傳下載的實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-08-08RadioGroup實(shí)現(xiàn)單選框的多行排列
這篇文章主要為大家詳細(xì)介紹了RadioGroup實(shí)現(xiàn)單選框的多行排列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Android開(kāi)發(fā)Compose集成高德地圖實(shí)例
這篇文章主要為大家介紹了Android開(kāi)發(fā)Compose里使用高德地圖實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08