flutter - 使用 BLoC 的 Flutter 导航:用于从 Navigator 推送路由的上下文必须是 Navigator 小部件的后代
问题描述
我正在使用 BLoC,我需要从 PageOne 导航到 PageTwo 并能够使用后退按钮返回,我不知道这是否是处理此问题的正确方法。调用函数_navigateToPage2时,我也会收到错误消息。
用于从 Navigator 推送或弹出路由的上下文必须是作为 Navigator 小部件后代的小部件的上下文。
class SimpleBlocDelegate extends BlocDelegate {
@override
void onTransition(Transition transition) {
print(transition);
}
@override
void onError(Object error, StackTrace stacktrace) {
print(error);
}
}
void main() {
BlocSupervisor().delegate = SimpleBlocDelegate();
runApp(MyApp(userRepository: UserRepository(GuriApi())));
}
class MyApp extends StatefulWidget {
final UserRepository userRepository;
MyApp({Key key, @required this.userRepository}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
AuthenticationBloc _authenticationBloc;
UserRepository get _userRepository => widget.userRepository;
@override
void initState() {
_authenticationBloc = AuthenticationBloc(userRepository: _userRepository);
_authenticationBloc.dispatch(AppStarted());
super.initState();
}
@override
void dispose() {
_authenticationBloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocProvider<AuthenticationBloc>(
bloc: _authenticationBloc,
child: MaterialApp(
theme: new ThemeData(
fontFamily: 'Monserrat',
primaryColor: Colors.lightBlue[50],
accentColor: Colors.white),
home: BlocBuilder<AuthenticationEvent, AuthenticationState>(
bloc: _authenticationBloc,
builder: (BuildContext context, AuthenticationState state) {
if (state is AuthenticationUninitialized) {
return SplashPage();
}
if (state is AuthenticationAuthenticated) {
return Home(userRepository: _userRepository);
}
if (state is AuthenticationUnauthenticated) {
return LoginPage(userRepository: _userRepository);
}
if (state is AuthenticationLoading) {
return LoadingIndicator();
}
if (state is PageOneSelected) {
return PageOne();
}
if (state is PageTwoSelected) {
_navigateToPage2();
}
},
),
),
);
}
_navigateToPage2() {
Navigator.of(context).push<bool>(
MaterialPageRoute(
builder: (BuildContext context) =>
PageTwo(userRepository: _userRepository)));
}
}
解决方案
我认为最好通过订阅 initState 中的 bloc 状态更改来处理导航:
@override
void initState() {
super.initState();
bloc.state.listen((state) {
if (state is PageOneSelected) {
_navigateToPage2();
} else if (state is PageTwoSelected) {
_navigateToPage2();
}
});
}
在构建方法中显示其他一些小部件。您的代码中发生错误,因为 blocBuilder 必须返回 Widget 但在 PageTwoSelected 状态的情况下您什么也不返回。
推荐阅读
- angular - 如何将@angular/platform-browser 添加到材质弹出对话框
- docker - boto3 dynamodb 连接到本地或远程实例
- ios - 如何将 UITextField 强制为数值列表?
- vue.js - 在 vue3 中通过 props 传递的组件
- json - 试图在python中更改我的csv文件的row2
- angular - 如何使用 *ngFor 仅显示最后 5 条消息
- c++ - 如何将 std::less 传递给类模板?
- apache-spark - Spark:将十六进制字符串转换为十进制
- javascript - 带有 devtools 的 WebdriverIO 正在控制台中打印大量数据
- c++ - 如何减少 MSVC 中的链接时间?