我遵循 BLoC 模式并订阅流,并对构建方法中的状态变化做出反应。加载数据后,我想关闭屏幕。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bloc'),
),
body: SafeArea(
child: StreamBuilder<UserState>(
stream: _userBloc.user,
initialData: UserInitState(),
builder: (context, snapshot) {
if (snapshot.data is UserInitState) {
return _buildInit();
}
if (snapshot.data is UserDataState) {
Navigator.pop(context, true);
return Container();
}
if (snapshot.data is UserLoadingState) {
return _buildLoading();
}
},
),
),
);
}
Run Code Online (Sandbox Code Playgroud)
当我Navigator.pop(context, true);使用build()方法时,我得到:
I/flutter ( 4360): ??? EXCEPTION CAUGHT BY ANIMATION LIBRARY ??????????????????????????????????????????????????????????
I/flutter ( 4360): The following assertion was thrown while notifying status listeners for AnimationController:
I/flutter ( 4360): setState() or markNeedsBuild() called during build.
I/flutter ( 4360): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter ( 4360): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter ( 4360): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter ( 4360): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter ( 4360): Otherwise, the framework might not visit this widget during this build phase.
Run Code Online (Sandbox Code Playgroud)
在 BLoC 模式中处理此类情况的正确方法是什么?
我提出的解决方案之一是开始收听initState(). 在这种情况下,我需要broadcast()我的流,因为我有 2 个订阅者。
有没有更好的解决方案?
小智 13
我想我已经为你找到了解决方案。(请检查一下)
让你的代码看起来像:
Widget build(BuildContext context) {
// other stuff
if (snapshot.data is UserDataState) {
myCallback(() {
Navigator.pop(context, true);
});
}
// other stuff
}
// after build method (but still in the same class,...) write below method
void myCallback(Function callback) {
WidgetsBinding.instance.addPostFrameCallback((_) {
callback();
});
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你。试试吧,请在这里报告以帮助他人!
我可以想象三种可能的解决方案:
1)在我看来,最好重组你的小部件。据我所知,您想要一个“加载屏幕”..我认为没有理由这必须是它自己的导航项,而不仅仅是另一个小部件。
IE。你可以推那个StreamBuilder吗?升级..所以你的构建器方法看起来像:
if (!snapshot.hasData) {
return LoadingScreen(snapshot);
}
// Whatever you do with your data.
Run Code Online (Sandbox Code Playgroud)
2)我想我个人会创建一个StatefulWidget,手动监听流initState()并setState()手动调用。不需要一个StreamBuilder
3)作为一个疯狂的解决方法,你可能会Future(() { Navigator.of(context).pop(); });在你的构建器中使用。(您可能必须使用context方法的build,而不是构建器。但无论如何我都不会推荐该解决方案)
| 归档时间: |
|
| 查看次数: |
4659 次 |
| 最近记录: |