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

使用Firestore数据结合FutureBuilder与ListView.builder时一直显示加载进度条问题

问题原因
  • 核心死循环问题:你在getChargingHistory方法末尾调用了setState,会触发当前Widget重新构建,而你在FutureBuilder的future参数直接写了getChargingHistory(),每次构建都会重新执行这个方法,方法执行完又触发setState,进入无限循环,永远无法进入ConnectionState.done状态。
  • 不合理的全局变量使用:你额外定义了全局变量qn存储请求结果,FutureBuilder本身会将异步请求的返回值存入snapshot.data,无需额外变量存储,也避免了变量异步赋值的时序问题。
  • 语法错误:你后续访问文档字段的写法qn.docs.data['Endzeit']有误,缺少对应索引和Firestore文档的data()方法调用,即使加载完成也会报错。
修正方案

1. 改造请求方法

去掉方法内的setState调用,直接返回QuerySnapshot即可:

Future<QuerySnapshot> getChargingHistory() async {
  return await users
      .doc('$currentUser')
      .collection('chargingHistory')
      .get();
}

2. 预先初始化Future

在State类中定义Future变量,在initState中初始化,避免每次build重复发起请求:

late Future<QuerySnapshot> chargingHistoryFuture;

@override
void initState() {
  super.initState();
  chargingHistoryFuture = getChargingHistory();
}

3. 改造FutureBuilder逻辑

直接使用snapshot.data获取返回结果,修正文档字段访问写法:

Expanded(
  child: FutureBuilder<QuerySnapshot>(
    future: chargingHistoryFuture,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        // 先判断是否有加载错误
        if (snapshot.hasError) {
          return Center(child: Text('加载失败:${snapshot.error}'));
        }
        // 获取文档列表
        List<QueryDocumentSnapshot> docs = snapshot.data!.docs;
        return ListView.builder(
          itemCount: docs.length,
          itemBuilder: (context, index) {
            Map<String, dynamic> docData = docs[index].data() as Map<String, dynamic>;
            return ListTile(
              title: Text(docData['Endzeit'].toString())
            );
          }
        );
      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
    }
  ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:57:00