【问题标题】:Navigator.pop from a FutureBuilder来自 FutureBuilder 的 Navigator.pop
【发布时间】:2020-07-11 00:47:51
【问题描述】:

我有一个要求用户输入的第一个屏幕,然后当用户单击一个按钮时,应用程序会进入第二个屏幕,该屏幕使用 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,但由于某些未知原因,它被多次调用

【问题讨论】:

  • 请分享您的代码????
  • 也发布错误。
  • 错误是什么?
  • 你能确认它在这条线上崩溃了吗? Navigator.pop(context, "an error");
  • 是的。我确认它在这条线上崩溃了。

标签: flutter state navigator


【解决方案1】:

构建方法运行时不能直接导航,所以最好显示一些错误屏幕并给使用机会返回上一个屏幕。

但是,如果您想这样做,那么您可以使用以下语句来这样做。

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

【讨论】:

  • 它似乎工作,但它被多次调用,所以它至少弹出两次......
  • 多次调用是什么意思,实际发生了什么?
  • 屏幕变黑。当我用调试器检查时,Future.microtask 被调用了两次,所以 Navigator.pop 也被调用了两次。我不知道为什么,但这就是发生的事情。但是,构建函数被多次调用似乎并不令人难以置信。
  • 你是如何学习这些东西的? “构建方法运行时无法直接导航”?我不知道,而且似乎没有充分的理由。
  • 屏幕构建时无法导航或调用setState,所以你必须这样做,或者你可以使用future等待微秒然后进行导航。
【解决方案2】:

我更愿意将 class 转换为 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在课外某处不是好方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2021-08-03
    • 2019-09-12
    • 1970-01-01
    • 2019-09-08
    相关资源
    最近更新 更多