如何将SliverList的childCount设置为Firebase集合的文档长度?
解决方法
你现在的核心问题是把FutureBuilder放在了列表项的构建逻辑里,不仅会重复触发Firestore请求,还因为请求异步执行,初始状态下count为空/默认值导致列表无法正确拿到长度。调整思路是把FutureBuilder上提至列表外层,请求完成后再渲染整个SliverList即可,修正后的代码如下:
// 首先调整getPosts方法,直接返回查询到的文档列表,不要用全局变量存值 Future<List<QueryDocumentSnapshot>> getPosts() async { var firestore = FirebaseFirestore.instance; final querySnapshot = await firestore.collection("Posts").get(); return querySnapshot.docs; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, // 把FutureBuilder套在CustomScrollView外层,全局只请求一次 body: FutureBuilder<List<QueryDocumentSnapshot>>( future: getPosts(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: Text('Loading', style: TextStyle(color: Colors.white),), ); } if (snapshot.hasError) { return const Center( child: Text('加载失败', style: TextStyle(color: Colors.white),), ); } // 拿到请求返回的文档列表 final posts = snapshot.data!; return CustomScrollView( slivers: <Widget>[ appBar, SliverList( delegate: SliverChildBuilderDelegate( (context, index) { // 直接用当前index取对应文档 final doc = posts[index]; return PostContainer( post: Post( user: UserModel( imageUrl: 'https://images.ctfassets.net/hrltx12pl8hq/7yQR5uJhwEkRfjwMFJ7bUK/dc52a0913e8ff8b5c276177890eb0129/offset_comp_772626-opt.jpg?fit=fill&w=800&h=300', name: doc.get('name'), ), caption: doc.get('Text') ?? null, timeAgo: '0 min', imageUrl: doc.get('img') ?? null, likes: 6345, comments: 15, shares: 18, views: 45 ), ); }, // 直接用文档列表的长度做childCount,不需要额外存count变量 childCount: posts.length, ) ) ], ); } ), ); }
本次调整的核心优化点:
- 移除了全局的
qn、count变量,直接让getPosts返回请求到的文档列表,避免状态污染 FutureBuilder上提后仅触发1次Firestore请求,大幅减少不必要的网络开销- 列表长度直接取返回的文档数组长度,不再依赖异步更新的全局变量,不会出现长度获取不到的问题
- 新增了错误状态处理,避免请求异常时页面无响应
内容的提问来源于stack exchange,提问作者Benjamin Frank
相关产品推荐
相关产品推荐

