通过在 NotificationListener 回调中调用 setState 在构建期间调用 Flutter 异常 `setState() 或 markNeedsBuild()`

代码

我很难弄清楚如何根据子视图“事件”更新视图的一部分……让我解释一下:

我有一个由 a 组成的屏幕Scaffold,作为一个body自定义小部件,它调用一个 rest api 来获取要显示的数据(它使用FutureBuilder),然后它发送一个通知(它基本上包装了 Flutter 的AsynchSnapshot)应该用于更新floatingActionButton(至少在我看来:P)。

这是build屏幕方法:

  @override
  Widget build(BuildContext context) {
    return NotificationListener<MyNotification>(
      onNotification: onMyNotification,
      child: Scaffold(
        appBar: MyAppBar(),
        body: MyRemoteObjectView(),
        floatingActionButton: MyFloatingButton(),
      ),
    );
  }

视图呈现完美,数据从服务器检索并显示,MyRemoteObjectView通知成功发送和接收,但是一旦我调用setState()我的回调,我就会收到异常:

在构建期间调用 setState() 或 markNeedsBuild() 。

这是回调(在上述build方法的同一类中定义):

bool onMyNotification(MyNotification notification) {
    AsyncSnapshot snapshot = notification.snapshot;

    if (snapshot.connectionState == ConnectionState.done) {
      setState(() {
        // these flags are used to customize the appearance and behavior of the floating button
        _serverHasBeenCalled = true;
        _modelDataRetrieved = snapshot.hasData;
      });
    }

    return true;
}

这是我发送通知的点(MyRemoteObjectView's 状态的构建方法):

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<T>(
      future: getData(),
      builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
        MyNotification(snapshot).dispatch(context);
        // ...

关键是:我应该如何以及何时告诉 Flutter 重绘浮动按钮(和/或其他小部件)?(因为当然没有setState我没有例外但按钮没有刷新)

我把整个事情都搞错了吗?有没有更简单的方法来做到这一点?让我知道

伊戈尔·卡拉霍丁

FutureBuilder构建完成后,等待 future 返回一个值。完成后,您将调用setState,然后将再次构建FutureBuilder,依此类推,导致无限重绘循环。

在这种情况下,您确定需要 FutureBuilder 和 NotificationListener 吗?您可能应该像这样在 StatefulWidget 的initState中执行此操作:

@override
void initState() {
  super.initState();

  getData().then((data) {
    setState(() {
      _serverHasBeenCalled = true;
      _modelDataRetrieved = true;
    });
  });
}

您还可以将Future存储在状态中并将其传递给FutureBuilder

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章