提问者:小点点

Flutter Future问题导致参数类型“Future<List<Widget>>”无法分配给参数类型“List<Widget>”错误


我的代码有问题。

本质上,我试图做的是从sqflite数据库中提取数据后动态创建显示文件信息的卡片。

我的问题是我的ListView的返回类型为

这是错误消息:

参数类型Future

这是从DB中提取数据的代码,并将生成的卡片小部件存储在列表itemsList

 Future<List<Widget>> getRecordedItems() async {
      List<Widget> itemsList = [];
      final dbHelper helper = dbHelper();
      var recordings = await helper.getRecordings();
      var len = recordings.length;

      for (var i = 0; i < len; i++) {
        var id = recordings[i]["id"];
        var filepath = recordings[i]["filepath"];
        var filelength = recordings[i]["length"];

        var loopCode = Card1(filepath, i, len, filelength);
        itemsList.add(loopCode);
      }
      return itemsList;
    }

这是我当前的back语句:

var items = getRecordedItems();
return ListView(children: items);

这是在另一个文件中接收ListView对象的代码:

Widget build(BuildContext context) {
    final AudioPlayerController audioController =
        Provider.of<AudioPlayerController>(context);

    return Scaffold(
        backgroundColor: AppColor.AppBackgroundColor,
        appBar: const PreferredSize(
            preferredSize: Size.fromHeight(kToolbarHeight), child: Titlebar()),
        body: Container(
            alignment: Alignment.center,
            child: Padding(
              padding: const EdgeInsets.all(8),
              child: Column(children: [
                const PastRecordingsHeader(name: "$name"),
                const Spacer(
                  flex: 1,
                ),
                SizedBox(
                    height: MediaQuery.of(context).size.height /1.67,
                    child: RecordingCard(name: '$name')
                   
                    )
              ]),
            )),
        bottomNavigationBar: PrevRecordingsNavBar();

RecordingCard()所在的位置

有人能帮我理解在哪里放置FutureBuilder吗?

尝试在ListView之外和ListView内部实现FutureBuilder,但无济于事。


共2个答案

匿名用户

要正确获取数据,您需要将(FutureBuilder)Widget放在您已经拥有的(ListView)Widget之上,在这种情况下,直到数据到来才会实现列表,因此要检查数据是否到来,您需要如下所示(if语句)以显示其他Widget,直到数据到来,函数完成后,您的列表将显示从函数中获取的数据。

 FutureBuilder<List<Widget>>(
              future: getRecordedItems(),
              builder: (context, data) {
                if (data.hasData) {
                  List<Widget> dataList = data.data!;
                  return ListView(children: dataList);
                } else {
                  Text(
                      'There is no data'); // put any widget you want in case there is no data
                }
              }),

匿名用户

您必须返回FutureBuilder而不是返回ListView,因此

Future<List<Widget>> items = [];
@override
void initState() {
  items = getRecordedItems(); // future is created just once, here!

  super.initState();
}

...
// somewhere further down in your build method:

return FutureBuilder<List<Widget>>(
  future: items, // do not create the future here!
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      List<Widget> items = snapshot.data ?? [];
      return ListView(children: items);
    } else { // if not yet done, return a progress indicator!
      return CircularProgressIndicator(); 
    }
}),

特别注意不要在未来:参数中创建未来,否则每次小部件重建时都会创建它!

有关这方面的更多信息,请参阅FutureBuilder本周章节的精彩小部件