flutter - 是否可以在 Flutter Navigator 中添加中间件?
问题描述
如果我有经过身份验证的 Firebase 用户,我会进行以下检查
if(await FirebaseAuth.instance.currentUser() == null)
Navigator.pushNamed(context, TheRegisterPage.routeName);
else
Navigator.pushNamed(context, TheGroupManagementPage.routeName);
而且我希望每次调用 Navigator 以导航到新路线时都执行此检查。有没有类似中间件的东西或我可以用来实现这一目标的其他方法?
我确实在https://api.flutter.dev/flutter/widgets/RouteObserver-class.html找到了 RouteObserver 类,但我注意到它的 didPush() 不是异步的,所以我无法异步检查是否在推送路由之前,我有一个经过身份验证的用户。我不喜欢为每条路线写一张支票的想法,因为它们都是一样的。那么有没有办法用 Flutter Navigator 实现某种异步中间件呢?
解决方案
这是一个应用程序的示例实现,您可以在DartPad中运行一个包装器Navigator
,您可以使用它来有条件地推送,也就是说,根据身份验证状态检查导航到页面或其他页面所需的任何身份验证确认.
请注意,FirstRoute
是 的子级AuthNavigator
。将构造函数中的条件更改AuthNavigator
为false,您将看到不同的导航。这里的关键是方法,以及从 中的静态方法pushConditionally
访问它的能力。context
of(BuildContext)
AuthNavigator
你可以做所有的条件检查async
,你只需要根据你的特定需要替换我someCondition
。
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: 'Navigation Basics',
home: AuthNavigator(
someCondition: true,
child: FirstRoute(),
),
),
);
}
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
AuthNavigator.of(context).pushConditionally(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
class ThirdRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("Third Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
class AuthNavigator extends StatefulWidget {
const AuthNavigator(
{@required this.child, @required this.someCondition, Key key})
: super(key: key);
final Widget child;
final bool someCondition;
static _AuthNavigatorState of(BuildContext context) =>
context.findAncestorStateOfType<_AuthNavigatorState>();
@override
_AuthNavigatorState createState() => _AuthNavigatorState();
}
class _AuthNavigatorState extends State<AuthNavigator> {
Future<T> pushConditionally<T extends Object>(
BuildContext context, Route<T> route) =>
widget.someCondition
? Navigator.push(
context,
MaterialPageRoute(builder: (context) => ThirdRoute()),
)
: Navigator.push(
context,
route,
);
@override
Widget build(BuildContext context) => widget.child;
}
如果您有任何疑问,请随时发表评论。
推荐阅读
- javascript - 在 MVC 项目中实现 autoNumeric v4
- sql-server - 如何从 SQL SERVER 的结果集中排除原始数据?
- java - Android Studio 为什么我每次都必须重新安装 sdk?
- electron - 在 Electron 中创建 exe 之外的文件夹
- android - 在 Android 上的 SQLite 数据库中实现相机图像存储的问题
- javascript - 选择特定选项时显示 div
- eclipse - 即使我在 Eclipse IDE 中安装了 Windowbuilder 也无法创建 JFrame
- neural-network - OCR 软件或自制 CNN 用于文档处理?
- ubuntu - vscode 没有运行并给出分段错误
- c# - 将“03/2020”之类的字符串解析为 DateTime 变量