Dart / Flutter:从使用异步方法获得的数据构建小部件

Dart / Flutter: building widget from data obtained using async method

我想使用 LietView.build 由 Widgets 填充,在构建 widget 之前从异步方法获取数据。这是我从网站收集数据的函数:

fetchBasicData(String URL) async {
  final response = await http.get(URL);
  var document = parse(response.body);

  var result = new List<dom.Node>();
  result = document.getElementsByClassName('datas-nev');
  var dogName = result[0].nodes[1].toString();
  result = document.getElementsByClassName('datas-tipus');
  var dogBreed = result[0].nodes[1].toString();
  result = document.getElementsByClassName('datas-nem');
  var dogGender = result[0].nodes[1].toString();
  result = document.getElementsByClassName('datas-szin');
  var dogColor = result[0].nodes[1].toString();
  result = document.getElementsByClassName('datas-kor');
  var dogAge = result[0].nodes[1].toString();

  result = document.getElementsByClassName('pirobox_gall');
  String imageLink;
  imageLink = urlPrefix + result[0].nodes[0].attributes.values.first;

  return new Dog.basic(
      URL,
      dogName,
      dogBreed,
      dogGender,
      dogColor,
      dogAge,
      imageLink);
}

函数已执行并收集数据,但小部件构建失败 type '_Future' is not a subtype of type 'Widget' of 'child' where

这是构建小部件的函数:

buildBasicWidget(String URL) async {
    Dog myDog = await fetchBasicData(URL);
    return new SizedBox(
      width: 500.0,
      height: 400.0,
      child: new Card(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            //Header image row
            new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Expanded(
                    child: new FutureBuilder(
                        future: fetchPortrait(myDog.imageLink),
                        builder: (context, snapshot) {
                          if (snapshot.hasData) {
                            return new Image.network(
                              snapshot.data,
                              fit: BoxFit.scaleDown,
                            );
                          } else {
                            if (snapshot.hasError) {
                              return new Text('Hiba');
                            }
                          }
                          return new Center(
                            child: new CircularProgressIndicator(),
                          );
                        }))
              ],
            ), //Header image row
            new Row(
              children: <Widget>[
                new Expanded(
                    child: new Text(
                  dogName,
                  style: new TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18.0,
                      color: Colors.black),
                ))
              ],
            ),
            new Row(
              children: <Widget>[
                new Expanded(
                    child: new Text(myDog.dogColor +
                        'színű, ' +
                        myDog.dogBreed +
                        ' ' +
                        myDog.dogGender))
              ],
            ),
            new Row(
              children: <Widget>[
                new Expanded(child: new Text('Kora: kb. ' + myDog.dogAge))
              ],
            )
          ],
        ),
      ),
    );
  }

我也尝试让这个函数异步,并让它等待 fetchBasicDetails() 完成,所以数据在它使用时就存在。

我什至尝试使用 dynamic fetchBasicData(String URL) async {...},但这也无济于事。 使用 Future<Dog> 而不是 dynamic 也会导致错误。

如何让 buildBasicWidget 使用 fetchBasicData 结果?或者我应该只处理 fetchBasicData 中的小部件构建作为一个简单的解决方法吗?

您需要使用 FutureBuilder 并在 future 参数中添加 async 函数,否则在获取数据之前会调用 build 方法。

或者在 initState 中执行异步请求。