Flutter路由管理插件fluro使用簡(jiǎn)介
前面兩篇文章我們介紹了Flutter 的原生導(dǎo)航器 Navigator 實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),路由及路由攔截的使用,具體可以參考之前的文章:
Flutter頁(yè)面路由及404路由攔截實(shí)現(xiàn)
Flutter實(shí)現(xiàn)路由參數(shù)傳遞及解析
使用原生的路由基本上能夠滿足大部分需求,但如果想要對(duì)頁(yè)面做類似瀏覽器 url 那樣的路由,或者控制頁(yè)面跳轉(zhuǎn)的轉(zhuǎn)場(chǎng)動(dòng)畫,那么原生的路由需要做不少的改造。在 pub
上,有優(yōu)秀的路由插件 fluro
解決這類問題。
fluro的使用方法
fluro 的使用步驟比較簡(jiǎn)單,分為下面三個(gè)步驟:
- 構(gòu)建
FluroRouter
路由實(shí)例,一個(gè)應(yīng)用一個(gè)實(shí)例即可; - 定義路由路徑的處理器(
Handler
),用于匹配不同路由路徑的處理方法。 - 在
MaterialApp
中把onGenerateRoute
設(shè)置為FluroRouter.generator
方法來(lái)構(gòu)建系統(tǒng)路由。
需要注意的是,F(xiàn)luro 默認(rèn)會(huì)把路徑“/”當(dāng)做根目錄,因此必須定義根目錄的 Handler
。另外對(duì)于路由不存在的情況,可以設(shè)置FluroRouter.notFoundHandler
定義錯(cuò)誤路由處理器。
路由處理器Handler
fluro 的關(guān)鍵實(shí)現(xiàn)是 Handler
,Handler
的定義如下:
class Handler { Handler({this.type = HandlerType.route, required this.handlerFunc}); final HandlerType type; final HandlerFunc handlerFunc; }
構(gòu)造函數(shù)有兩個(gè)屬性,一個(gè)是 HandlerType
枚舉,分為 route
和 function
兩個(gè)值,其中用于路由的是 route
,也是默認(rèn)值。handlerFunc
是必傳的,這是響應(yīng)路由的一個(gè)方法,需要返回一個(gè) Widget
,以便跳轉(zhuǎn)到對(duì)應(yīng)的頁(yè)面。
typedef Widget? HandlerFunc( BuildContext? context, Map<String, List<String>> parameters);
HandlerFunc
接收上下文 context
,以及攜帶了路由參數(shù),這個(gè)參數(shù)是一個(gè)Map
,對(duì)應(yīng)路由路徑的多個(gè)路由參數(shù)。例如/dynamic/:id
路由,如果實(shí)際路由為/dynamic/1?event=a&event=b
,則 parameters
的格式如下:
{ "id": ["1"], "event": ["a", "b"] }
需要注意路由參數(shù)的數(shù)據(jù)類型全部是String
類型,通過這個(gè) Handler
,可以將路由參數(shù)傳遞到下級(jí)頁(yè)面。
使用示例
我們?yōu)榱私y(tǒng)一管理路由,定義一個(gè)類 RouterManager
,里面的屬性均為靜態(tài)成員,以便直接通過類訪問,而無(wú)需創(chuàng)建示例。當(dāng)然考慮封裝性,也可以做成單例模式。需要注意,FluroRouter
只能初始化一次,否則會(huì)導(dǎo)致熱重載報(bào)錯(cuò)提示路由已經(jīng)被定義。我們把上兩篇的路由跳轉(zhuǎn)替換為fluro
跳轉(zhuǎn),RouterManager
的代碼如下:
//省略 import class RouterManager { static String splashPath = '/'; static String loginPath = '/login'; static String homePath = '/home'; static String dynamicPath = '/dynamic'; static String dynamicDetailPath = '$dynamicPath/:id'; static FluroRouter router; static void initRouter() { if (router == null) { router = FluroRouter(); defineRoutes(); } } static var loginHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return LoginPage(); }); static var dynamicDetailHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return DynamicDetailPage(params['id'][0]); }); static var splashHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return Splash(); }); static var homeHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return AppHomePage(); }); static var notFoundHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return NotFound(); }); static void defineRoutes() { router.define(splashPath, handler: splashHandler); router.define(homePath, handler: homeHandler); router.define(loginPath, handler: loginHandler); router.define(dynamicDetailPath, handler: dynamicDetailHandler); router.notFoundHandler = notFoundHandler; } }
實(shí)際只需要調(diào)用 RouterManager.initRouter
方法即可完成路由的初始化,這個(gè)需要在 main.dart
的 MaterialApp
中完成,代碼如下。與之前的代碼相比,不再需要設(shè)置navigationKey
參數(shù)和 initialRoute
參數(shù),只是需要在 build
方法里調(diào)用初始化路由的方法。
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { RouterManager.initRouter(); return MaterialApp( //... onGenerateRoute: RouterManager.router.generator, ); } }
頁(yè)面跳轉(zhuǎn)
頁(yè)面跳轉(zhuǎn)調(diào)用有多種形式,本例我們用到了三種,分別是:
清除路由堆棧跳轉(zhuǎn):即跳轉(zhuǎn)后的頁(yè)面作為根頁(yè)面(沒有返回按鈕),這種適合閃屏頁(yè)跳到首頁(yè)。代碼如下:
RouterManager.router.navigateTo(context, RouterManager.homePath, clearStack: true);
普通跳轉(zhuǎn):無(wú)參數(shù)直接跳轉(zhuǎn),代碼如下:
RouterManager.router.navigateTo(context, RouterManager.loginPath);
帶參數(shù)跳轉(zhuǎn):路由路徑攜帶參數(shù),和普通跳轉(zhuǎn)類似,只是拼接了路徑參數(shù)和 query 參數(shù):
RouterManager.router.navigateTo(context, '${RouterManager.dynamicPath}/$id?event=a&event=b')
運(yùn)行效果
我們將閃屏頁(yè)跳轉(zhuǎn)到首頁(yè),動(dòng)態(tài)跳轉(zhuǎn)到詳情頁(yè),以及登錄頁(yè)和404頁(yè)面進(jìn)行了更換,運(yùn)行效果如下圖所示。注意看整個(gè)轉(zhuǎn)場(chǎng)方式的不同,正常的轉(zhuǎn)場(chǎng)切換是從底部到頂部彈出,但404是從左到右彈出(和原生的 push
一樣)。這個(gè)后續(xù)可以在 Handler
里調(diào)整或者在路由跳轉(zhuǎn)的時(shí)候定義轉(zhuǎn)場(chǎng)動(dòng)畫,我們下一篇再來(lái)介紹這方面的使用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)多線程下載圖片的方法
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)多線程下載圖片的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android中Serializable和Parcelable序列化對(duì)象詳解
這篇文章主要介紹了Android中Serializable和Parcelable序列化對(duì)象的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-02-02Android TabHost選項(xiàng)卡標(biāo)簽圖標(biāo)始終不出現(xiàn)的解決方法
這篇文章主要介紹了Android TabHost選項(xiàng)卡標(biāo)簽圖標(biāo)始終不出現(xiàn)的解決方法,涉及Android界面布局相關(guān)屬性與狀態(tài)設(shè)置操作技巧,需要的朋友可以參考下2019-03-03android基礎(chǔ)總結(jié)篇之一:Activity生命周期
本篇文章主要介紹了android基礎(chǔ)總結(jié)篇之一:Activity生命周期,想要學(xué)習(xí)的可以了解一下。2016-11-11android利用service完成計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了android利用service完成計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Android RecyclerView實(shí)現(xiàn)水平、垂直方向分割線
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView實(shí)現(xiàn)水平、垂直方向分割線,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07