Flutter中在FutureBuilder内调用ListView.builder总是崩溃如何解决?
Flutter项目中水平ListView搭配Firestore加载数据崩溃问题解决
问题描述
使用cloud_firestore开发Flutter应用,需求为展示用户信息列表,在FutureBuilder中调用ListView.builder时应用持续崩溃。
初始代码
List<dynamic> infoList = <dynamic>[]; @override Widget build(BuildContext context) { return Scaffold( appBar: originAppBar(context, pageNames.discovery), body: Center( child: FutureBuilder<DocumentSnapshot>( future: FirebaseFirestore.instance .collection("users") .doc(FirebaseAuth.instance.currentUser!.uid) .get(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData && snapshot.data!.exists) { return ListView.builder( shrinkWrap: true, itemCount: infoList.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index) { return Text(infoList[index]); }); } return const Center(child: LinearProgressIndicator()); }, ), )); }
前置验证
通过以下代码验证可正常获取数据:
if (snapshot.hasData && snapshot.data!.exists) { Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>; infoList = data["info"]; for (int i = 0; i < infoList.length; i++) { print(infoList[i].toString()); } }
打印可正常输出对应字符串,但运行时抛出异常。
核心报错信息
Horizontal viewport was given unbounded height(水平视口被赋予了无界高度)
报错原因有两点:一是水平滚动的ListView在交叉轴(垂直方向)没有获取到明确的高度约束;二是初始业务代码漏了将Firestore返回的快照数据赋值给渲染用的infoList数组。
修复后可运行代码
List<dynamic> infoList = <dynamic>[]; body: Center( child: FutureBuilder<DocumentSnapshot>( future: FirebaseFirestore.instance .collection("users") .doc(FirebaseAuth.instance.currentUser!.uid) .get(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData && snapshot.data!.exists) { Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>; infoList = data["info"]; // 给水平ListView加明确高度约束,避免布局无界报错 return SizedBox( height: 40, child: ListView.builder( shrinkWrap: true, itemCount: infoList.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index) { return Text(infoList[index]); } ), ); } return const Center(child: LinearProgressIndicator()); }, ), )
修复要点
- 拿到Firestore的DocumentSnapshot后,手动将目标数据字段赋值给infoList数组,保证渲染数据源有效
- 水平滚动的ListView必须在垂直方向有明确的高度约束,可通过外层包裹SizedBox、Container指定height属性实现
内容的提问来源于stack exchange,提问作者Beginner_
相关产品推荐
相关产品推荐

