【问题标题】:Error trying to build a ListView in a Flutter FutureBuilder尝试在 Flutter FutureBuilder 中构建 ListView 时出错
【发布时间】:2021-09-08 00:31:43
【问题描述】:

我是 Flutter 的新手,正在构建一个小应用程序来记录我的开支并学习一点。

我正在使用 Hive 来存储数据。现在我正在构建一个页面,该页面旨在显示所有以前保存的条目。为此,我创建了一个包含所有数据的列表,然后尝试使用 FutureBuilder 在 ListView 中显示数据。

这是目前为止的代码:


class LogScreen extends StatefulWidget {
  const LogScreen({Key? key}) : super(key: key);

  @override
  _LogScreenState createState() => _LogScreenState();
}

class _LogScreenState extends State<LogScreen> {
  get futureEntries => getEntries();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Widget>(
        future: futureEntries,
        builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
          if (snapshot.hasData) {
            return Container(
                child: ListView.builder(
                  itemCount: futureEntries.length,
                  itemBuilder: (context, index) {
                    Entry currentEntry = Hive.box<Entry>('entriesBox').getAt(index);
                    return ListTile(
                      title: Text('${currentEntry.description}'),
                    );
                  },
                ),
            );
          } else {
              return CircularProgressIndicator();
          }
        }
    );
  }

  Future<List> getEntries() async {
    List listEntries = await DbHelper().getListEntries();
    print(listEntries);
    return listEntries;
  }

}

我收到以下错误:

The following _TypeError was thrown building LogScreen(dirty, state: _LogScreenState#75644):
type 'Future<List<dynamic>>' is not a subtype of type 'Future<Widget>?'

The relevant error-causing widget was: 
  LogScreen file:///home/javier/StudioProjects/finanzas/lib/main.dart:55:14
When the exception was thrown, this was the stack: 
#0      _LogScreenState.build (package:finanzas/log_screen.dart:29:17)

有人可以告诉我我做错了什么并提出解决方案吗?我来自 Python,并且在所有这些类型上都度过了一段时光:-P

提前致谢。

【问题讨论】:

    标签: flutter flutter-hive


    【解决方案1】:

    FutureBuilder&lt;T&gt;() 的泛型类型应该对应于您的Future 将返回的数据类型,而不是构建器正在构建的数据类型。在您的情况下,您有FutureBuilder&lt;Widget&gt;,因此它需要Future&lt;Widget&gt;,但您的getEntries 返回Future&lt;List&lt;dynamic&gt;&gt;。所以这就是错误所暗示的。您的代码应该如下所示:

    return FutureBuilder<List<Entry>>(
            future: futureEntries,
            builder: (BuildContext context, AsyncSnapshot<List<Entry>> snapshot) {
              if (snapshot.hasData) {
                return Container(
                    child: ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (context, index) {
                        Entry currentEntry = snapshot.data[index];
                        return ListTile(
                          title: Text('${currentEntry.description}'),
                        );
                      },
                    ),
                );
              } else {
                  return CircularProgressIndicator();
              }
            }
        );
    

    另请注意,我将您的 ListView.builder 中的引用从直接引用您的未来替换为使用 snapshot 中的数据

    【讨论】:

    • 非常感谢您的回复。那绝对可以。我更正了它,现在我在该行出现错误:itemCount:snapshot.data.length,IDE 告诉我 snapshot.data 可能为空,我应该考虑这种情况。不应该只在快照有一些数据的情况下执行该分支吗?
    • 是的,但是 null 安全不能确定,因为您检查了上面的 hasData ,这将是非空的。你可以做snapshot.data!.length
    【解决方案2】:

    好的。经过一番研究,下面是开始工作的代码:

      Widget build(BuildContext context) {
        return FutureBuilder<List>(
            future: futureEntries,
            builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
              if (snapshot.hasData) {
                return Container(
                    child: ListView.builder(
                      itemCount: snapshot.data!.length,
                      itemBuilder: (context, index) {
                        Entry currentEntry = snapshot.data![index];
                        return ListTile(
                          title: Text('${currentEntry.description}'),
                        );
                      },
                    ),
                );
              } else {
                  return CircularProgressIndicator();
              }
            }
        );
      }
    
      Future<List> getEntries() async {
        List listEntries = await DbHelper().getListEntries();
        print(listEntries);
        return listEntries;
      }
    
    

    我还不知道“数据”后面的感叹号到底是做什么的,但他们做到了。

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 2020-02-22
      • 2021-03-31
      • 2021-01-22
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      相关资源
      最近更新 更多