在Flutter開發中,全局的Toast
/Loading
很狗血,實現已有的實現方法都不是很人性化。最近在Dio作請求攔截器的時候Overlay
一直獲取不到context
,每一個頁面進入都存一遍很不方便,若是在MaterialApp
中存context,那麼調用Navigator.of(context).pushReplacementNamed
等removeUtils
的操做時都會報錯。android
除了以上坑點。在使用命名路由的時候動畫Flutter也沒提供修改方法。Navigator.pushNamed(context, "/login");
若是是android
那麼動畫就是從下而上,一點都不fashion。git
Flutter的路由很特殊,若是想實現一個Router鉤子要怎麼辦呢? - -!
我就是樣攔截路由,不管是埋點或者是之前其餘特殊功能。都須要一個統一的路由調度。程序員
爲了解決上面的Flutter坑點,聯繫Web端很是流行的SPA
應用,若是咱們的頁面一直是單頁那麼context
就是全局的。並且能夠實現頁面的攔截器。很是nice
。github
直接上代碼,首先實現一個單頁的頁面管理器。 so easy...bash
MaterialApp(
home: ManagerPage(),
// ...
)
複製代碼
而後是頁面管理器ManagerPage
的實現,利用Flutter自帶的Navigator
,不熟悉的童鞋能夠看看我之前寫的關於Navigator
的文章。app
Widget build(BuildContext context) {
// 利用 EventBus 來調度
eventBus.on('showToast', (message) {
Toast.show(context, message);
});
return Navigator( // 實現SPA
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
// 路由表對應單頁
Widget _page = ZRouter.routerStore[settings.name];
// 埋點等操做
// 自定義路由動畫
return CupertinoPageRoute(
settings: settings,
builder: (context) => _page
);
}
);
}
複製代碼
關於routerStore
,一個SPA路由表動畫
static Map<String, Widget> get routerStore => {
'/': SplashPage(),
'/main_page': NavPage(),
'/login': LoginPage(),
'/product_detail': ProductDetailsPage()
};
複製代碼
在子頁面使用ui
// 直接經過 Navigator.pushNamed 命名路由和傳參。
Navigator.pushNamed(context, "/login", arguments: RouteArguments<String>('想從活動登錄'));
// 使用全局toast
eventBus.emit('showToast', '系統繁忙請稍後再試...');
複製代碼
對請求攔截器的適配spa
onResponse: (Response response) {
// 在返回響應數據以前作一些預處理
if (response.data['code'] != '000') {
eventBus.emit('showToast', '系統繁忙請稍後再試...');
}
return response;
},
onError: (DioError error) {
// 當請求失敗時作一些預處理
eventBus.emit('showToast', '程序員GG正在想問題...');
return error;
}
複製代碼