在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...app
MaterialApp( home: ManagerPage(), // ... )
而后是页面管理器ManagerPage
的实现,利用Flutter自带的Navigator
,不熟悉的童鞋能够看看我之前写的关于Navigator
的文章。动画
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路由表ui
static Map<String, Widget> get routerStore => { '/': SplashPage(), '/main_page': NavPage(), '/login': LoginPage(), '/product_detail': ProductDetailsPage() };
在子页面使用code
// 直接经过 Navigator.pushNamed 命名路由和传参。 Navigator.pushNamed(context, "/login", arguments: RouteArguments<String>('想从活动登录')); // 使用全局toast eventBus.emit('showToast', '系统繁忙请稍后再试...');
对请求拦截器的适配router
onResponse: (Response response) { // 在返回响应数据以前作一些预处理 if (response.data['code'] != '000') { eventBus.emit('showToast', '系统繁忙请稍后再试...'); } return response; }, onError: (DioError error) { // 当请求失败时作一些预处理 eventBus.emit('showToast', '程序员GG正在想问题...'); return error; }