Flutter中ListView.builder无数据时如何正确显示Lottie动画?
解决Flutter中Firestore空数据时Lottie动画重复显示的问题
你之前的问题出在把空状态的Lottie放在了ListView的itemBuilder里,这会导致:
- 当有数据时,每个列表项都会渲染一次动画,出现重复显示的情况
- 当数据为空时,itemCount为0,itemBuilder不会执行,反而看不到动画
正确的做法是在ListView外部判断数据是否为空,分情况渲染UI:
核心逻辑
- 先判断从Firestore获取的日程列表是否为空
- 空数据时,直接显示Lottie动画(通常放在Center里,保证居中显示)
- 有数据时,正常渲染ListView列表项
代码示例
假设你用StreamBuilder从Firestore获取数据,完整实现代码如下:
Widget build(BuildContext context) { return StreamBuilder<List<YourScheduleModel>>( // 替换成你获取对应日期日程的流逻辑 stream: FirebaseFirestore.instance .collection('schedules') .where('date', isEqualTo: selectedDate.toIso8601String()) .snapshots() .map((snapshot) => snapshot.docs.map((doc) => YourScheduleModel.fromDoc(doc)).toList()), builder: (context, snapshot) { // 处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 处理错误状态 if (snapshot.hasError) { return const Center(child: Text('加载日程失败')); } final schedules = snapshot.data ?? []; // 判断数据是否为空 if (schedules.isEmpty) { // 空数据时显示Lottie动画 return Center( child: Lottie.asset( 'assets/no_schedule_animation.json', // 替换为你的Lottie文件路径 width: 220, height: 220, ), ); } else { // 有数据时渲染列表 return ListView.builder( padding: const EdgeInsets.symmetric(vertical: 12), itemCount: schedules.length, itemBuilder: (context, index) { final schedule = schedules[index]; // 替换为你的日程项组件 return ScheduleCard( title: schedule.title, time: schedule.time, // 其他自定义属性 ); }, ); } }, ); }
关键说明
- 不要在
itemBuilder里处理空状态:itemBuilder是用来渲染单个列表项的,空状态属于整个列表的全局状态,必须在ListView外层判断 - 务必处理加载和错误状态:异步获取数据时,这两个状态能避免用户看到空白或异常界面
- 确认Lottie资源配置:保证你的Lottie JSON文件放在
assets目录下,并且在pubspec.yaml中正确声明了资源路径
内容的提问来源于stack exchange,提问作者I Can Done
相关产品推荐
相关产品推荐

