Flutter路由傳遞參數(shù)及解析實(shí)現(xiàn)
上一篇Flutter頁面路由及404路由攔截實(shí)現(xiàn)介紹了使用路由來實(shí)現(xiàn)頁面的跳轉(zhuǎn),從而簡(jiǎn)化頁面之間的耦合,并可以實(shí)現(xiàn)路由攔截。在實(shí)際開發(fā)中,我們經(jīng)常會(huì)需要在頁面跳轉(zhuǎn)的時(shí)候攜帶路由參數(shù),典型的例子就是從列表到詳情頁的時(shí)候,需要攜帶詳情的 id,以便詳情頁獲取對(duì)應(yīng)的數(shù)據(jù)。同時(shí),有些時(shí)候還需要返回時(shí)攜帶參數(shù)返回上一級(jí),以便上級(jí)頁面根據(jù)返回結(jié)果更新。本篇將介紹這兩種情形的實(shí)現(xiàn)。
Navigator 的 push 和 pop方法
Navigator
導(dǎo)航器的 push
和 pop
方法可以攜帶參數(shù)在頁面間傳遞,其他變形的方法也一樣。pushNamed
方法原型如下:
Future<T?> pushNamed<T extends Object?>( String routeName, { Object? arguments, }) { return push<T>(_routeNamed<T>(routeName, arguments: arguments)!); }
除了 routeName
的命名路由以外,還有個(gè)可選參數(shù) arguments
用于在路由頁面?zhèn)鬟f參數(shù)。pop
方法也一樣:
void pop<T extends Object?>([ T? result ]) { //... }
可以攜帶一個(gè) result
回傳到上級(jí)頁面。
代碼實(shí)現(xiàn)
我們使用一個(gè)列表跳轉(zhuǎn)到詳情頁來演示路由參數(shù)獲?。斜順?gòu)建文章請(qǐng)看Flutter 入門與實(shí)戰(zhàn)(五):來一個(gè)圖文并茂的列表)。點(diǎn)擊列表行時(shí)攜帶列表數(shù)據(jù)項(xiàng)的 id 跳轉(zhuǎn)到詳情頁。從詳情頁返回時(shí)再把該 id 回傳。列表項(xiàng)的 Widget 新增了一個(gè) id屬性,由構(gòu)建列表時(shí)初始化得到。
class DynamicItem extends StatelessWidget { final int id; final String title; final String imageUrl; final int viewCount; static const double ITEM_HEIGHT = 100; static const double TITLE_HEIGHT = 80; static const double MARGIN_SIZE = 10; const DynamicItem(this.id, this.title, this.imageUrl, this.viewCount, {Key key}) : super(key: key); //... }
列表的容器使用 GestureDetector
包裹,以便響應(yīng)點(diǎn)擊事件。 onTap
方法定義為一個(gè) async
方法,以便使用 await
獲取導(dǎo)航返回時(shí)的參數(shù),并使用一個(gè) SnackBar
顯示返回的 id
。這里 pushNamed
攜帶了一個(gè) Map
對(duì)象將列表的 id
傳遞到詳情頁。
@override Widget build(BuildContext context) { return GestureDetector( child: Container( margin: EdgeInsets.all(MARGIN_SIZE), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ _imageWrapper(this.imageUrl), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _titleWrapper(context, this.title), _viewCountWrapper(this.viewCount.toString()), ], ), ) ], ), ), onTap: () async { Map<String, dynamic> routeParams = {'id': id}; var arguments = await Navigator.of(context) .pushNamed(RouterTable.dynamicDetail, arguments: routeParams); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("從動(dòng)態(tài)${(arguments as Map<String, dynamic>)['id']}返回"), )); }, ); }
這里還使用了一個(gè) arguments
變量 接收導(dǎo)航返回的參數(shù),導(dǎo)航若有返回參數(shù),會(huì)返回一個(gè) Future
對(duì)象,使用 await
即可接收。然后在使用 as
轉(zhuǎn)換為實(shí)際的類型進(jìn)行使用。
在詳情頁中,F(xiàn)lutter 提供了一個(gè)ModalRoute
的類從當(dāng)前上下文獲取路由配置參數(shù),代碼如下所示:
class DynamicDetail extends StatelessWidget { const DynamicDetail({Key key}) : super(key: key); @override Widget build(BuildContext context) { Map<String, dynamic> routeParams = ModalRoute.of(context).settings?.arguments; return WillPopScope( child: Scaffold( appBar: AppBar( title: Text('動(dòng)態(tài)詳情'), brightness: Brightness.dark, ), body: Center( child: Text("產(chǎn)品 id: ${routeParams['id']}"), ), ), onWillPop: () async { Navigator.of(context).pop({'id': routeParams['id']}); return true; }, ); } }
實(shí)際上這個(gè)ModalRoute.of(context).settings
就是我們上一篇路由攔截中的onGenerateRoute
的 settings
參數(shù),因此假設(shè)我們需要增加額外的路由參數(shù)(例如全局參數(shù)),則可以在 onGenerateRoute
方法中重新組裝路由參數(shù)。
這里有個(gè)地方需要注意,因?yàn)榉祷貢r(shí)要攜帶參數(shù),因此我們需要攔截返回響應(yīng)事件,這時(shí)候整個(gè)組件可以使用 WillPopScope
包裹,該方法帶有兩個(gè)參數(shù):
child
:子組件,即原有的頁面組件;onWillPop
:返回前攔截處理,返回一個(gè)Future<bool>
對(duì)象,若為false
,則不會(huì)返回。若為true
,則返回上一級(jí)。這里我們調(diào)用了 攜帶參數(shù)的pop
方法以便將參數(shù)回傳。實(shí)際這里往往做一些其他處理,例如表單沒有保存時(shí)詢問是否確認(rèn)離開,還有廣大電商的活動(dòng)頁詢問你是“忍痛離開”或是“再看一會(huì)”的處理。
最終效果
最終運(yùn)行效果如下圖所示,詳情頁獲取到了 id
參數(shù),返回的時(shí)候也接收到了對(duì)應(yīng)的 id
。
路由參數(shù)攔截
路由參數(shù)可以通過 onGenerateRoute
攔截進(jìn)行額外處理,示例代碼如下。需要注意,這里僅僅是示例,由于 settings
。arguments
可能為任意類型,因此可能會(huì)導(dǎo)致轉(zhuǎn)換失敗。實(shí)際業(yè)務(wù)中最好是約定路由參數(shù)傳遞類型,避免參數(shù)形式不統(tǒng)一導(dǎo)致異常出現(xiàn)。
static Route onGenerateRoute<T extends Object>(RouteSettings settings) { var arguments = settings.arguments as Map<String, dynamic>; if (arguments != null) { arguments['event'] = '路由攔截增加的參數(shù)'; } RouteSettings newSettings = settings.copyWith(name: settings.name, arguments: arguments); return CupertinoPageRoute<T>( settings: newSettings, builder: (context) { String name = settings.name; if (routeTables[name] == null) { name = notFoundPath; } Widget widget = routeTables[name](context); return widget; }, ); }
總結(jié)
本篇介紹了路由參數(shù)的傳遞示例以及路由攔截后參數(shù)修改,在實(shí)際過程中一般是往下級(jí)傳遞路由參數(shù),需要盡量避免來回傳參來實(shí)現(xiàn)數(shù)據(jù)傳遞導(dǎo)致上下級(jí)頁面耦合嚴(yán)重,最好通過狀態(tài)管理實(shí)現(xiàn)。目前這種路由管理也會(huì)存在一定的不便之處,比如無法像網(wǎng)頁的 url 一樣在路徑名傳遞可變參數(shù),以及無法控制頁面跳轉(zhuǎn)的轉(zhuǎn)場(chǎng)動(dòng)畫。在 pub 上fluro
路由管理非常流行,下一篇介紹如何使用 fluro
實(shí)現(xiàn)頁面路由。
到此這篇關(guān)于Flutter路由傳遞參數(shù)及解析實(shí)現(xiàn)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android學(xué)習(xí)筆記-保存數(shù)據(jù)到SQL數(shù)據(jù)庫中(Saving Data in SQL Databases)
這篇文章主要介紹了Android學(xué)習(xí)筆記-保存數(shù)據(jù)到SQL數(shù)據(jù)庫中的(Saving Data in SQL Databases)2014-10-10Android 5.0中CoordinatorLayout的使用技巧
這篇文章主要為大家詳細(xì)介紹了Android 5.0中CoordinatorLayout的使用技巧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09詳解AndroidStudio3.0開發(fā)調(diào)試安卓NDK的C++代碼
這篇文章主要介紹了AndroidStudio3.0開發(fā)調(diào)試安卓NDK的C++代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12Android studio實(shí)現(xiàn)刮刮樂的方法
這篇文章主要為大家詳細(xì)介紹了Android studio實(shí)現(xiàn)刮刮樂的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Android11及以上文件讀寫權(quán)限申請(qǐng)?jiān)敿?xì)介紹
安卓11改變了此前安卓系統(tǒng)對(duì)于文件管理的規(guī)則,在安卓 11 上,文件讀寫變成了特殊權(quán)限,下面這篇文章主要給大家介紹了關(guān)于Android11及以上文件讀寫權(quán)限申請(qǐng)的相關(guān)資料,需要的朋友可以參考下2022-08-08Android實(shí)現(xiàn)將一個(gè)Activity設(shè)置成窗口樣式的方法
這篇文章主要介紹了Android實(shí)現(xiàn)將一個(gè)Activity設(shè)置成窗口樣式的方法,涉及Android的窗口樣式設(shè)置與布局技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-02-02Android中編寫簡(jiǎn)單的手電筒小應(yīng)用的實(shí)例教程
這篇文章主要介紹了Android中編寫簡(jiǎn)單的手電筒小應(yīng)用的實(shí)例教程,簡(jiǎn)單粗暴地控制手機(jī)閃光燈的開閉,效果拔群XD 需要的朋友可以參考下2016-04-04android選擇視頻文件上傳到后臺(tái)服務(wù)器
這篇文章主要介紹了android選擇視頻文件上傳到后臺(tái)服務(wù)器的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Android中的SpannableString與SpannableStringBuilder詳解
這篇文章主要給大家介紹了關(guān)于Android中SpannableString與SpannableStringBuilder的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10