使用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
相关产品推荐
相关产品推荐

