为什么 snapshot.data.length 出现错误?

Sho*_*har 1 dart flutter flutter-futurebuilder

我正在尝试从 API 解析数据。为此,我使用 FutureBuilder 在 ListView 中列出所有解析的数据。

我已经执行了无效检查,snapshot.data但我继续在段中收到此错误snapshot.data.length,它说,The property 'length' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!').

我在本节中也有类似的错误snapshot.data[i],其中写着The method '[]' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!').

这是我的代码部分:

 body: Container(
        child: FutureBuilder(
          future: getData('hello'),
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return Container(
                child: Text("Loading"),
              );
            }else{
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, i) {
                    return ListTile(
                      title: snapshot.data[i].partOfSpeech,
                    );
                  });
            }
          },
        ),
      ),
Run Code Online (Sandbox Code Playgroud)

这是 getData(String s):

Future<List> getData(String s) async {
  var response = await http
      .get(Uri.https('api.dictionaryapi.dev', 'api/v2/entries/en_US/' + s));
  var jsonData = jsonDecode(response.body)[0];

  List<Data> data = [];

  for (var x in jsonData["meanings"]) {
    String definition = x["definitions"][0]["definition"];
    Data d = Data(x["partOfSpeech"], definition);
    data.add(d);
  }

  return data;
}
Run Code Online (Sandbox Code Playgroud)

Sho*_*har 5

继续这个答案,我找到了解决我的问题的方法。显然 getData 没有按预期返回列表。相反,它返回一个对象。

将对象类型转换为列表解决了这个问题。

这是更正后的代码:

body: Container(
        child: FutureBuilder(
          future: getData('hello'),
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return Container(
                child: Text("Loading"),
              );
            }else{
              //typecasting Object to List
              var data = (snapshot.data as List<Data>).toList();
              return ListView.builder(
                  itemCount: data.length,
                  itemBuilder: (context, i) {
                    return ListTile(
                      title: data[i].partOfSpeech,
                    );
                  });
            }
          },
        ),
      ),
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您使用的是新版本的 flutter(2.2.0 或更高版本)。首先尝试向目标添加空检查('!')。因为零安全功能。

 body: Container(
    child: FutureBuilder(
      future: getData('hello'),
      builder: (context, snapshot) {
        if (snapshot.data == null) {
          return Container(
            child: Text("Loading"),
          );
        }else{
          return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, i) {
                return ListTile(
                  title: snapshot.data[i].partOfSpeech,
                );
              });
        }
      },
    ),
  ),
Run Code Online (Sandbox Code Playgroud)

然后尝试将 FutureBuilder 类型指定为数据类型列表

 body: Container(
    child: FutureBuilder<List<Data>>(
      future: getData('hello'),
      builder: (context, snapshot) {
        if (snapshot.data == null) {
          return Container(
            child: Text("Loading"),
          );
        }else{
          return ListView.builder(
              itemCount: snapshot.data.length,
              itemBuilder: (context, i) {
                return ListTile(
                  title: snapshot.data[i].partOfSpeech,
                );
              });
        }
      },
    ),
  ),
Run Code Online (Sandbox Code Playgroud)