You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为FutureBuilder创建动态Future列表?Flutter开发问题

解决方案:预存Future列表,避免重复查询且支持异步加载

核心思路是存储每个页面对应的查询Future,而非直接存储查询结果,这样既不会因为Widget重建重复触发数据库查询,又能让各个页面的查询异步执行,第一页数据加载完成后即可立即显示。

步骤1:定义Future列表

把之前存储实际数据的列表改成存储Future的列表:

late List<Future<List<Map<String, dynamic>>>> futureList;

步骤2:在initState中初始化Future列表

不需要await每个查询,直接把每个数据库查询的Future添加到列表里,这样每个查询会立即异步执行:

@override
void initState() {
  super.initState();
  // 初始化列表,长度与longList一致,直接生成每个页面的查询Future
  futureList = List.generate(widget.longList.length, (index) {
    return SQLHelper.getExamples(widget.longList[index]["foo"]);
  });
}

步骤3:在PageView中使用FutureBuilder

直接用futureList[pageIndex]作为FutureBuilder的future参数,每个页面对应自己的查询Future:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: PageView.builder(
      itemCount: widget.longList.length,
      itemBuilder: (context, pageIndex) {
        return FutureBuilder<List<Map<String, dynamic>>>(
          future: futureList[pageIndex],
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              final exampleList = snapshot.data!;
              // 注意:exampleList是当前页面的子列表,无需再用pageIndex索引
              return Column(
                children: [
                  Text("这是第$pageIndex页,数据:${exampleList.toString()}"),
                ],
              );
            } else if (snapshot.hasError) {
              return Center(child: Text("加载出错:${snapshot.error}"));
            } else {
              return const Center(child: CircularProgressIndicator());
            }
          },
        );
      },
    ),
  );
}

为什么之前的方法不行?

你之前的代码里,futureList存储的是查询完成后的实际数据,但createList()是异步函数,initState执行完毕时futureList还没被填充(甚至可能未完成初始化),访问futureList[pageIndex]会报错或返回空。而存储Future列表的话,列表在initState里就完成初始化,每个元素都是已经启动的查询Future,FutureBuilder可以正常监听它的状态变化。


备选:使用Future.wait(不推荐,不符合你的需求)

如果一定要等所有查询完成再显示所有页面,可以用Future.wait,但这样第一页也需要等待所有查询完成才能显示:

late Future<List<List<Map<String, dynamic>>>> allFutures;

@override
void initState() {
  super.initState();
  // 收集所有查询Future,等待全部完成
  allFutures = Future.wait([
    for (var item in widget.longList)
      SQLHelper.getExamples(item["foo"]),
  ]);
}

// 对应PageView使用方式
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder<List<List<Map<String, dynamic>>>>(
      future: allFutures,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          final allData = snapshot.data!;
          return PageView.builder(
            itemCount: widget.longList.length,
            itemBuilder: (context, pageIndex) {
              final exampleList = allData[pageIndex];
              return Column(
                children: [
                  Text("这是第$pageIndex页,数据:${exampleList.toString()}"),
                ],
              );
            },
          );
        } else {
          return const Center(child: CircularProgressIndicator());
        }
      },
    ),
  );
}

内容的提问来源于stack exchange,提问作者Yakagami Subaru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:05:24