全局Toast/Loading问题
在Flutter开发中,全局的Toast
/Loading
很狗血,实现已有的实现方法都不是很人性化。最近在Dio做请求拦截器的时候Overlay
一直获取不到context
,每个页面进入都存一遍很不方便,如果在MaterialApp
中存context,那么调用Navigator.of(context).pushReplacementNamed
等removeUtils
的操作时都会报错。
全局自定义命名路由动画问题
除了以上坑点。在使用命名路由的时候动画Flutter也没提供修改方法。Navigator.pushNamed(context, "/login");
如果是android
那么动画就是从下而上,一点都不fashion。
页面路由拦截器问题
Flutter的路由很特殊,如果想实现一个Router钩子要怎么办呢? - -!
我就是样拦截路由,无论是埋点或者是以前其他特殊功能。都需要一个统一的路由调度。
解决思路
为了解决上面的Flutter坑点,联系Web端非常流行的SPA
应用,如果我们的页面一直是单页那么context
就是全局的。而且可以实现页面的拦截器。非常nice
。
SPA 单页面应用解决方案
直接上代码,首先实现一个单页的页面管理器。 so easy...
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路由表
static Map<String, Widget> get routerStore => {
'/': SplashPage(),
'/main_page': NavPage(),
'/login': LoginPage(),
'/product_detail': ProductDetailsPage()
};
在子页面使用
// 直接通过 Navigator.pushNamed 命名路由和传参。
Navigator.pushNamed(context, "/login", arguments: RouteArguments<String>('想从活动登陆'));
// 使用全局toast
eventBus.emit('showToast', '系统繁忙请稍后再试...');
对请求拦截器的适配
onResponse: (Response response) {
// 在返回响应数据之前做一些预处理
if (response.data['code'] != '000') {
eventBus.emit('showToast', '系统繁忙请稍后再试...');
}
return response;
},
onError: (DioError error) {
// 当请求失败时做一些预处理
eventBus.emit('showToast', '程序员GG正在想问题...');
return error;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。