Flutter開發中的路由參數處理
Navigator 的 push 和 pop方法
Navigator 導航器的 push 和 pop 方法可以攜帶參數在頁面間傳遞,其他變形的方法也一樣。pushNamed 方法原型如下:
Future<T?> pushNamed<T extends Object?>( String routeName, { Object? arguments, }) { return push<T>(_routeNamed<T>(routeName, arguments: arguments)!); }
除瞭 routeName 的命名路由以外,還有個可選參數 arguments 用於在路由頁面傳遞參數。pop 方法也一樣:
void pop<T extends Object?>([ T? result ]) { //... }
可以攜帶一個 result 回傳到上級頁面。
代碼實現
我們使用一個列表跳轉到詳情頁來演示路由參數獲取(列表構建文章請看//www.jb51.net/article/213052.htm)。點擊列表行時攜帶列表數據項的 id 跳轉到詳情頁。從詳情頁返回時再把該 id 回傳。列表項的 Widget 新增瞭一個 id屬性,由構建列表時初始化得到。
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 包裹,以便響應點擊事件。 onTap 方法定義為一個 async 方法,以便使用 await 獲取導航返回時的參數,並使用一個 SnackBar 顯示返回的 id。這裡 pushNamed 攜帶瞭一個 Map 對象將列表的 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("從動態${(arguments as Map<String, dynamic>)['id']}返回"), )); }, ); }
這裡還使用瞭一個 arguments變量 接收導航返回的參數,導航若有返回參數,會返回一個 Future 對象,使用 await 即可接收。然後在使用 as 轉換為實際的類型進行使用。 在詳情頁中,Flutter 提供瞭一個ModalRoute的類從當前上下文獲取路由配置參數,代碼如下所示:
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('動態詳情'), brightness: Brightness.dark, ), body: Center( child: Text("產品 id: ${routeParams['id']}"), ), ), onWillPop: () async { Navigator.of(context).pop({'id': routeParams['id']}); return true; }, ); } }
實際上這個ModalRoute.of(context).settings就是我們上一篇路由攔截中的onGenerateRoute的 settings 參數,因此假設我們需要增加額外的路由參數(例如全局參數),則可以在 onGenerateRoute 方法中重新組裝路由參數。 這裡有個地方需要註意,因為返回時要攜帶參數,因此我們需要攔截返回響應事件,這時候整個組件可以使用 WillPopScope 包裹,該方法帶有兩個參數:
- child:子組件,即原有的頁面組件;
- onWillPop:返回前攔截處理,返回一個 Future<bool>對象,若為 false,則不會返回。若為 true,則返回上一級。這裡我們調用瞭 攜帶參數的 pop 方法以便將參數回傳。實際這裡往往做一些其他處理,例如表單沒有保存詢問是否確認李可,還有廣大電商的活動頁詢問你是“忍痛離開”或是“再看一會”的處理。
最終效果
最終運行效果如下圖所示,詳情頁獲取到瞭 id 參數,返回的時候也接收到瞭對應的 id。
以上就是Flutter開發中的路由參數處理的詳細內容,更多關於Flutter 路由參數處理的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Flutter添加頁面過渡動畫實現步驟
- Flutter WillPopScope攔截返回事件原理示例詳解
- flutter狀態管理Provider的使用學習
- MaterialApp Flutter 應用全局配置與主題管理詳解
- Flutter 給列表增加下拉刷新和上滑加載更多功能