Flutter-在FutureBuilder中等待setState然后加载组件

时间:2019-11-26 15:26:41

标签: flutter

我正在尝试类似的方法。在Future Builder中加载服务,设置“文本字段”值,然后编写组件。

 final data = FutureBuilder(
            future: DatameterService.getMapData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                setState(() {
                  calleController.text = snapshot.data.calle;
                  paisController.text = snapshot.data.pais;
                  provinciaController.text = snapshot.data.provincia;
                  poblacionController.text = snapshot.data.poblacion;
                  postalController.text = snapshot.data.postal;
                });
                return form;
              } else {
                return indicator;
              }

但是返回

  在构建过程中调用

setState()或markNeedsBuild()。

问题是:如何使用FutureBuilder填充TextField输入值?

2 个答案:

答案 0 :(得分:0)

永远不要在构建中调用setState,原因很简单:setState导致构建,并且构建调用setState-您处于无限循环中。因此,引擎会明确告诉您,您不应尝试这样做。

实际上,您不应该在build内部执行任何业务逻辑。从您的代码看来,您想要在页面出现时加载一些数据,并为TextField设置一些初始字段。我想您不想在这里使用FutureBuilder,因为您有StatefulWidget。相反,您可以将未来移出内部版本,并在initState中调用它。

类似这样的东西:

class _MyState extends State<MyWidget> {
  Map<String, dynamic> _data;
  bool _loading;
  TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    // start fetching
    _loading = true;
    _data = {};
    _controller = TextEditingController();
    getData().then((data) {
      setState(() {
        _data = data;
        _loading = false;
        _controller.text = _data['text'];
      });
    });
  }

  Widget build(BuildContext context) {
    // handle loading vs. not loading
    if (_loading) return CircularProgressIndicator();
    return Container(
      // the rest of your code
    );
  }
}

您甚至不需要存储_data,但是它对于重置表单或其他内容很有用。

答案 1 :(得分:0)

基本上,您需要了解如何调用FutureBuilderFutureBuilder有一个子future:,您为其分配了一个附加了.then的异步方法。异步过程完成后,将调用“ .then”。

得出答案,您可以通过这种方式调用setState。

myFutureMethod.then((value) => {
      setState(() {
        value = true;
      })
    });