来自FutureBuilder的Navigator.pop

时间:2020-03-30 15:37:56

标签: flutter state navigator

我有第一个屏幕,要求用户输入输入内容,然后在用户单击按钮时,应用程序进入第二个屏幕,该屏幕使用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();
            },
          )
      ),
    );
  }
}

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

2 个答案:

答案 0 :(得分:2)

运行构建方法时不能直接导航,因此最好显示一些错误屏幕,并有机会回到最后一个屏幕。

但是,如果要这样做,可以使用以下语句来实现。

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

答案 1 :(得分:1)

我希望将类转换为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(),
      ),
    );
  }
}

并且在课堂外某处通过context的原因并不是很好的方法