【问题标题】:Why FutureBuilder doesn't get call in Flutter?为什么 FutureBuilder 在 Flutter 中没有被调用?
【发布时间】:2018-07-04 06:35:03
【问题描述】:

我的屏幕上有一个按钮,每当我点击它时我都会打电话给_fetchPost()。此方法调用fetchPost()。当我在var post = ... 行上设置断点时,我能够看到我解析的对象。但是,我的问题是 builder 不会被调用。

我是 Flutter 的新手,所以我的代码有问题吗?

void _fetchPost() {
    FutureBuilder<Post>(
      future: fetchPost(),
      builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
        if (snapshot.hasData) {
          String res = snapshot.data.parm1.toString() + snapshot.data.op + snapshot.data.parm2.toString();
          setState(() {
            _result = res;
          });
        } else if (snapshot.hasError) {
          setState(() {
            _result = snapshot.error;
          });
        }

        // By default, show a loading spinner
        return CircularProgressIndicator();
      },
    );
  }

  Future<Post> fetchPost() async {
    final response = await http.get('http://test.ethorstat.com/test.ashx');
    if (response.statusCode == 200) {
      // If server returns an OK response, parse the JSON
      var post = Post.fromJason(json.decode(response.body));
      return post;
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post!');
    }
  }

【问题讨论】:

  • 嗨,赫萨姆。我是这里的一名志愿者编辑,我们喜欢做的一件事就是为了简洁而编辑问题和答案。特别是,在技术写作中不需要诸如感谢、赞赏、称呼和签名之类的细节,我们不鼓励这样做。本文已在 Meta 上对此进行了讨论:Should I remove 'fluff' when editing questions?
  • @hesam 你能帮我解决这个相同类型的问题吗? stackoverflow.com/questions/64540805/…

标签: dart flutter


【解决方案1】:

FutureBuilder 是一个小部件。这意味着为了让它工作,你需要先将它插入到小部件树中

您可以将FutureBuilder 添加到小部件树中,方法是将其作为子级返回到另一个小部件,或者直接返回到小部件的build 函数:

class FetchWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) => FutureBuilder<Post>(
    future: fetchPost(),
    builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
      if (snapshot.hasData) {
        String res = snapshot.data.parm1.toString() + snapshot.data.op + snapshot.data.parm2.toString();
        setState(() { // setState will not work here, I only used this StatelessWidget to show what I mean with inserting it into the build tree
          _result = res;
        });
      } else if (snapshot.hasError) {
        setState(() {
          _result = snapshot.error;
        });
      }

      // By default, show a loading spinner
      return CircularProgressIndicator();
    },
  );

  Future<Post> fetchPost() async {
    final response = await http.get('http://test.ethorstat.com/test.ashx');
    if (response.statusCode == 200) {
      // If server returns an OK response, parse the JSON
     var post = Post.fromJason(json.decode(response.body));
     return post;
    } else {
      // If that response was not OK, throw an error.
     throw Exception('Failed to load post!');
    }
  }
}

这不会编译,因为我只是将您的代码复制到了一个StatelessWidget,它没有setState。我只想通过说 “将 [...] 添加到小部件树”来说明我的意思

或者你可以使用普通的async await 来做你想做的事情:

void _fetchPost() async {
  final Post fetchedPost = await fetchPost();
  final String res = fetchedPost.parm1.toString() + fetchedPost.op + fetchedPost.parm2.toString();
  setState(() {
    _result = res;
  });
}

我不确定你想如何实现你的fetchPost,但是如果你想使用FutureBuilder,你需要将它插入到小部件树中,并将一个小部件返回给builder

【讨论】:

  • 谢谢。所以,我的理解是错误的。我想我可以使用FutureBuilder 来从后端下载一些东西。
  • FutureBuilder 是一种在wiget 树中以简洁的方式处理Future 的方法。在函数中等待Future 就可以了。
  • @creativecreatorormaybenot 你能帮我解决这个相同类型的问题吗? stackoverflow.com/questions/64540805/…
猜你喜欢
  • 2020-01-07
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多