Flutter 来自FutureBuilder的Navigator.pop

Flutter 来自FutureBuilder的Navigator.pop,flutter,state,navigator,Flutter,State,Navigator,我有一个第一个屏幕,要求用户输入,然后当用户点击按钮时,应用程序进入第二个屏幕,使用FutureBuilder调用API 如果API返回错误,我想使用Navigator.pop返回上一个屏幕。当我尝试在FutureBuilder的生成器中执行此操作时,我会得到一个错误,因为我在构建树时修改了树 在生成过程中调用setState()或markNeedsBuild()。这个覆盖层 无法将小部件标记为需要构建,因为该框架是 已经在构建小部件的过程中 如果发生错误,正确的方法是什么 class Stac

我有一个第一个屏幕,要求用户输入,然后当用户点击按钮时,应用程序进入第二个屏幕,使用FutureBuilder调用API

如果API返回错误,我想使用Navigator.pop返回上一个屏幕。当我尝试在FutureBuilder的生成器中执行此操作时,我会得到一个错误,因为我在构建树时修改了树

在生成过程中调用setState()或markNeedsBuild()。这个覆盖层 无法将小部件标记为需要构建,因为该框架是 已经在构建小部件的过程中

如果发生错误,正确的方法是什么

class Stackoverflow extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<Flight>(
            future: fetchData(context),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ScreenBody(snapshot.data);
              } else if (snapshot.hasError) {
                Navigator.pop(context, "an error");
              }
              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          )
      ),
    );
  }
}
类Stackoverflow扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:未来建设者(
未来:获取数据(上下文),
生成器:(上下文,快照){
if(snapshot.hasData){
返回屏幕主体(snapshot.data);
}else if(snapshot.hasrerror){
pop(上下文,“一个错误”);
}
//默认情况下,显示加载微调器。
返回循环ProgressIndicator();
},
)
),
);
}
}

PS:我尝试使用addPostFrameCallback并在内部使用Navigator.pop,但由于未知原因,它被多次调用

当构建方法运行时,您无法直接导航,因此最好显示一些错误屏幕,并让我们有机会返回到上一个屏幕

然而,如果您想这样做,那么您可以使用下面的语句来这样做

Future.microtask(() => Navigator.pop(context));

当构建方法运行时,您不能直接导航,所以最好显示一些错误屏幕,并让您有机会返回到上一个屏幕

然而,如果您想这样做,那么您可以使用下面的语句来这样做

Future.microtask(() => Navigator.pop(context));

我更愿意将类转换为
StateFullWidget
,并摆脱
FutureBuilder

class Stackoverflow extends StatefulWidget {

  @override
  _StackoverflowState createState() => _StackoverflowState();
}

class _StackoverflowState extends State<Stackoverflow> {
  Flight flight;

  @override
  void initState() {
    super.initState();
    fetchData().then((data) {
      setState(() {
        flight = data;
      });
    }).catchError((e) {
      Navigator.pop(context, "an error");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: flight != null ? ScreenBody(flight) : CircularProgressIndicator(),
      ),
    );
  }
}
类Stackoverflow扩展了StatefulWidget{
@凌驾
_StackoverflowState createState()=>\u StackoverflowState();
}
类_StackoverflowState扩展状态{
飞行;
@凌驾
void initState(){
super.initState();
fetchData()。然后((数据){
设置状态(){
飞行=数据;
});
}).catchError((e){
pop(上下文,“一个错误”);
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子项:flight!=null?屏幕主体(flight):CircularProgressIndicator(),
),
);
}
}

当然,在类之外的某个地方传递
context
不是一个好方法

我更愿意将类转换为
StateFullWidget
并摆脱
FutureBuilder

class Stackoverflow extends StatefulWidget {

  @override
  _StackoverflowState createState() => _StackoverflowState();
}

class _StackoverflowState extends State<Stackoverflow> {
  Flight flight;

  @override
  void initState() {
    super.initState();
    fetchData().then((data) {
      setState(() {
        flight = data;
      });
    }).catchError((e) {
      Navigator.pop(context, "an error");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: flight != null ? ScreenBody(flight) : CircularProgressIndicator(),
      ),
    );
  }
}
类Stackoverflow扩展了StatefulWidget{
@凌驾
_StackoverflowState createState()=>\u StackoverflowState();
}
类_StackoverflowState扩展状态{
飞行;
@凌驾
void initState(){
super.initState();
fetchData()。然后((数据){
设置状态(){
飞行=数据;
});
}).catchError((e){
pop(上下文,“一个错误”);
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子项:flight!=null?屏幕主体(flight):CircularProgressIndicator(),
),
);
}
}


当然,pass
context
在课堂之外的某个地方不是一个好方法

请将您的代码也分享给我们。错误是什么?您能确认它在这一行崩溃了吗<代码>Navigator.pop(上下文,“一个错误”)是。我确认它在这条线上崩溃了。请分享你的错误代码。错误是什么?你能确认它在这条线上崩溃了吗<代码>Navigator.pop(上下文,“一个错误”)是。我确认它在这条线上崩溃了。它似乎可以工作,但它被多次调用,所以它至少会弹出两次…你说它多次调用是什么意思?实际上发生了什么?屏幕变黑了。当我使用调试器检查时,Future.microtask会被调用两次,因此Navigator.pop也会被调用两次。我不知道为什么,但事情就是这样。然而,构建函数被多次调用似乎并不令人难以置信。你是如何学习这些东西的?“无法在生成方法运行时直接导航”?我不知道,似乎也没有什么好的理由。当屏幕构建时,你不能导航或调用setState,所以你必须这样做,或者你可以使用future等待微秒,然后进行导航。它似乎可以工作,但它被多次调用,所以它至少会弹出两次…你说的多次调用是什么意思?实际发生了什么?屏幕变黑了。当我使用调试器检查时,Future.microtask会被调用两次,因此Navigator.pop也会被调用两次。我不知道为什么,但事情就是这样。然而,构建函数被多次调用似乎并不令人难以置信。你是如何学习这些东西的?“无法在生成方法运行时直接导航”?我不知道,这似乎没有一个好的理由。当屏幕构建时,您不能导航或调用setState,所以您必须这样做,或者您可以使用future等待微秒,然后再进行导航。