编辑:使用此解决方案几个月后,我注意到它存在一些问题:
- Android 硬件后退按钮不起作用
- 当您切换“检查”模式时,应用程序将重置。
- 无法进行过渡
- 不保证不显示禁止路线
所以我不再推荐使用这种方法!
对于正常的用户启动的导航,您根本不需要 BLoC 模式。只需使用Navigator
.
登录是一种特殊情况。遵循 BLoC 模式,提供一个isAuthenticated
stream:
abstract class MyBloc {
Stream<bool> get isAuthenticated;
}
您的应用程序可能有 2 种不同的命名路由树:一种用于登录用户,一种用于匿名用户:
final Map<String, WidgetBuilder> anonymousRoutes = {
'/': (context) => new LoginScreen(), // default for anon
'/register': (context) => new RegisterScreen(),
};
final Map<String, WidgetBuilder> authenticatedRoutes = {
'/': (context) => new HomeScreen(), // default for logged in
'/savings': (context) => new SavingsScreen(),
// ...
};
通常情况下Navigator
并且它的命名路由与MaterialApp
,但您也可以定义自己的,当isAuthenticated
流已更新:
class MyApp extends StatelessWidget {
const MyApp({Key key, this.bloc}) : super(key: key);
final MyBloc bloc;
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (BuildContext context, Widget child) {
return StreamBuilder<bool>(
stream: bloc.isAuthenticated,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return Text('loading...');
}
bool isAuthenticated = snapshot.data;
return _buildNavigator(isAuthenticated);
},
);
},
);
}
}
Navigator _buildNavigator(bool isAuthenticated) {
// different route tree and different default route depending on auth state
final routes = isAuthenticated ? authenticatedRoutes : anonymousRoutes;
return Navigator(
key: new ValueKey(isAuthenticated),
onGenerateRoute: (RouteSettings settings) {
final name = settings.name;
return new MaterialPageRoute(
builder: routes[name],
settings: settings,
);
},
onUnknownRoute: (RouteSettings settings) {
throw Exception('unknown route');
},
);
}
现在可悲了(2018-07-14)有 2 个相互矛盾的断言 https://github.com/flutter/flutter/issues/18904在 Flutter 代码中,您必须删除该代码才能使上面的代码正常工作(您可以使用 IDE 对其进行编辑):
93号线和96号线packages\flutter\lib\src\widgets\app.dart
//assert(navigatorObservers != null),
//assert(onGenerateRoute != null || navigatorObservers == const <NavigatorObserver>[]),