Flutter项目中如何展示Firebase的QueryDocumentSnapshot数据到Card组件
第一步:修复模型解析报错
你触发FormatException的原因是直接对DocumentSnapshot实例执行toString(),拿到的是实例的调试描述字符串而非有效JSON内容。正确的做法是调用DocumentSnapshot的data()方法获取已经解析完成的Map<String, dynamic>类型数据,直接传入模型的fromJson方法即可:
Widget buildCard(BuildContext context, DocumentSnapshot week) { // 获取快照的原始结构化数据 Map<String, dynamic> weekRawData = week.data() as Map<String, dynamic>; // 直接传入模型解析,不需要额外做字符串转码 final DataFromWeek dataFromWeek = DataFromWeek.fromJson(weekRawData); return Card( margin: const EdgeInsets.all(10), child: Padding( padding: const EdgeInsets.all(12), child: buildWeekContent(dataFromWeek), ), ); }
第二步:嵌套遍历动态数据构建UI
你的数据是两层Map嵌套结构(天映射 -> 单天内活动映射),可以直接通过Map的values属性遍历所有条目,不需要提前知道具体的天序号、活动时间戳等key值:
Widget buildWeekContent(DataFromWeek data) { // 按天序号排序(可选,不需要可以删除这部分逻辑) final sortedDayEntries = data.days.entries.toList() ..sort((a, b) => int.parse(a.key).compareTo(int.parse(b.key))); return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: sortedDayEntries.length, itemBuilder: (context, dayIndex) { final dayEntry = sortedDayEntries[dayIndex]; final dayNumber = dayEntry.key; final currentDay = dayEntry.value; // 获取当天所有活动列表 final activities = currentDay.activities.values.toList(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 天标题 Text( "第$dayNumber天", style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), // 当天活动列表 ...activities.map((activity) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ // 完成状态标记 Icon( activity.finished ? Icons.check_circle : Icons.radio_button_unchecked, size: 16, color: activity.finished ? Colors.green : Colors.grey, ), const SizedBox(width: 8), // 活动内容 Expanded(child: Text(activity.query)), const SizedBox(width: 8), // 活动时长 Text("${activity.duration}小时", style: const TextStyle(color: Colors.grey)), ], ), ); }).toList(), const SizedBox(height: 12), ], ); }, ); }
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

