Flutter(Dart)中如何访问嵌套实例对象内的列表并在FutureBuilder中渲染
问题解决方法
打印显示Instance of 'License'说明
这是正常现象,你已经将接口返回的JSON成功反序列化为Dart实体类对象,默认打印只会输出类实例标识。如果需要打印JSON内容,只需给License实体类重写toString()方法,或者实现toJson()方法即可,该情况不影响界面渲染。
列表渲染为空的核心原因&修复
你的代码存在两个核心错误:
- 调用
x.map()后没有执行.toList(),Dart中map方法返回的是Iterable类型,无法直接作为组件列表渲染 - 你没有将
map生成的组件列表作为返回值传递给FutureBuilder,相当于生成的组件完全没有挂载到Widget树上
修正后的代码示例
body: SingleChildScrollView( child: FutureBuilder<Profile>( future: _license, builder: (context, snapshot) { if (snapshot.hasData == false || snapshot.data == null) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text("${snapshot.error}")); } else { List<License> licenseList = snapshot.data!.license; // 把生成的组件列表放到Column中返回 return Column( crossAxisAlignment: CrossAxisAlignment.start, children: licenseList.map((e) { // 可在此处打印确认属性是否正常获取 debugPrint(e.fromDate); return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("证件号:${e.licenseNo}"), Text("生效日期:${e.fromDate}"), Text("失效日期:${e.toDate}"), Text("工作地点:${e.workStation ?? "无"}"), const SizedBox(height: 12) ], ) ], ); }).toList(), // 必须调用.toList()将Iterable转为Widget列表 ); } } ) )
可选:用ListView实现的写法
如果需要使用ListView渲染,需添加shrinkWrap和physics属性避免和外层SingleChildScrollView的滚动冲突:
return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: licenseList.length, itemBuilder: (context, index) { License item = licenseList[index]; return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("证件号:${item.licenseNo}"), Text("生效日期:${item.fromDate}"), const SizedBox(height: 12) ], ) ], ); } );
额外注意事项
如果打印e.fromDate为null,请检查你的License实体类的字段注解是否正确:JSON返回的字段是下划线命名from_date,如果你的实体类用的是驼峰命名fromDate,需要添加对应的字段映射,比如使用json_serializable时要加@JsonKey(name: 'from_date')注解。
内容的提问来源于stack exchange,提问作者shiro
相关产品推荐
相关产品推荐

