我正在构建一个简单的Flutter应用。它的启动屏幕确定用户是否已登录,并根据该信息随后重定向到登录屏幕或主/主屏幕。
我的启动屏幕是StatefulWidget
,其状态如下所示。它使用扩展了ChangeNotifier
的ViewModel类(它的代码是无关紧要的,因此我没有包括它)。
class _LaunchPageState extends State<LaunchPage> {
LaunchViewModel _viewModel = LaunchViewModel();
@override
void initState() {
super.initState();
_viewModel.checkSessionStatus();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<LaunchViewModel>(
builder: (_) => _viewModel,
child: Scaffold(
body: Consumer<LaunchViewModel>(
builder: (context, viewModel, _) {
if (viewModel.state is LaunchInitial) {
return CircularProgressIndicator();
}
if (viewModel.state is LaunchLoginPage) {
Navigator.pushNamed(context, "login");
}
if (viewModel.state is LaunchMainPage) {
Navigator.pushNamed(context, "main");
}
return Container();
},
),
),
);
}
}
ViewModel发出3种状态之一:
可以很好地处理LaunchInitial状态,并在屏幕上显示进度条。但是其他2种状态会导致应用崩溃。引发以下错误:
This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets
似乎在执行消费者的build
方法时尝试重定向到另一个屏幕导致了此问题。正确的方法是什么?
谢谢!
答案 0 :(得分:0)
您无法在小部件树中直接调用Navigator
。如果您拥有event-state
构建器,那么最好更改要渲染的窗口小部件树:
builder: (context, viewModel, _) {
if (viewModel.state is LaunchInitial) {
return CircularProgressIndicator();
}
if (viewModel.state is LaunchLoginPage) {
return LoginPage();
}
if (viewModel.state is LaunchMainPage) {
return MainPage();
}
return Container();
},
您必须使用Widget
方法中的每个孩子返回build
。
或者,您也可以使用Navigation
:
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (viewModel.state is LaunchInitial) {
return CircularProgressIndicator();
}
if (viewModel.state is LaunchLoginPage) {
Navigator.pushNamed(context, "login");
}
if (viewModel.state is LaunchMainPage) {
Navigator.pushNamed(context, "main");
}
return Container();
});
super.initState();
}
addPostFrameCallback
方法将被称为正确完成build
方法的答案,您可以在其中导航。