私有API列表集成到ListView时数据不显示问题排查
私有API候选人列表无法在ListView中展示的问题排查
问题描述
将私有API返回的候选人列表集成到Flutter的ListView时遇到问题:应用运行时,API响应中的candList对象列表无法在ListView中正常展示。
API响应结构
{ "currentPage": 1, "totalPages": 1, "totalResults": 4, "candList": [ {"fname": "string", "lname": "string"}, {"fname": "another", "lname": "person"} ] }
疑似问题代码段
final num = getJsonField(listViewGetCandListByManagerResponse.jsonBody, r'''$.candList''',).toList(); if (num.isEmpty) { return Center( child: SworkerContainerWidget( fname: GetCandListByManagerCall.workerfname(listViewGetCandListByManagerResponse.jsonBody,).toString(), lname: GetCandListByManagerCall.workerlname(listViewGetCandListByManagerResponse.jsonBody,).toString(), ), ); } return ListView.builder( padding: EdgeInsets.zero, scrollDirection: Axis.vertical, itemCount: num.length, itemBuilder: (context, numIndex) { final numItem = num[numIndex]; return InkWell( onTap: () async { await Navigator.push( context, MaterialPageRoute( builder: (context) => HistoryPageWidget(), ), ); }, child: SworkerContainerWidget( desc: GetCandListByManagerCall .workereventDesc( listViewGetCandListByManagerResponse .jsonBody, ).toString(), fname: GetCandListByManagerCall.workerfname( listViewGetCandListByManagerResponse .jsonBody, ).toString(), lname: GetCandListByManagerCall.workerlname( listViewGetCandListByManagerResponse .jsonBody, ).toString(), dateEvent: GetCandListByManagerCall.dateEvent( listViewGetCandListByManagerResponse .jsonBody, ).toString(), ), ); }, );
相关工具方法及API调用类
getJsonField工具方法
dynamic getJsonField(dynamic response, String jsonPath) { final field = JsonPath(JsonPath).read(response); return field.isNotEmpty ? field.length > 1 ? field.map((f) => f.value).toList() : field.first.value : null; }
GetCandListByManagerCall API调用类
class GetCandListByManagerCall { static Future<ApiCallResponse> call({int? entityId}) { final body = { "token": "", // 已删除敏感内容 "entityId": entityId, "pageNumber": 1, "rowsPerPage": 10, "search": "" }; return Apimanager.instance.makeApicall(callName:'GetCandListByManager',....); } static dynamic workerfname(dynamic response) => getJsonField(response, r'''$.fname''',); static dynamic workerlname(dynamic response) => getJsonField(response, r'''$.lname''',); }
问题分析与修复方案
核心问题1:ListView item数据获取错误
在itemBuilder中,已经拿到了当前遍历的候选人对象numItem,但调用GetCandListByManagerCall的方法时,传入的是整个API响应体而非当前的numItem,导致所有item读取的是同一套(甚至不存在的)数据。
核心问题2:JsonPath初始化错误
getJsonField方法中,JsonPath(JsonPath)是错误写法,应该传入参数jsonPath,否则无法正确解析指定路径的字段。
补充问题:空状态逻辑不合理
空状态下的SworkerContainerWidget不应该读取整个响应体的fname/lname(此时candList为空,这些字段不存在),应替换为提示文本。
修复后的代码
修复getJsonField方法
dynamic getJsonField(dynamic response, String jsonPath) { final field = JsonPath(jsonPath).read(response); // 修复JsonPath初始化 return field.isNotEmpty ? field.length > 1 ? field.map((f) => f.value).toList() : field.first.value : null; }
修复ListView及空状态逻辑
final candList = getJsonField(listViewGetCandListByManagerResponse.jsonBody, r'''$.candList''') as List? ?? []; if (candList.isEmpty) { return const Center( child: Text("暂无候选人数据"), ); } return ListView.builder( padding: EdgeInsets.zero, scrollDirection: Axis.vertical, itemCount: candList.length, itemBuilder: (context, index) { final candidate = candList[index]; return InkWell( onTap: () async { await Navigator.push( context, MaterialPageRoute( builder: (context) => HistoryPageWidget(), ), ); }, child: SworkerContainerWidget( desc: GetCandListByManagerCall.workereventDesc(candidate).toString(), fname: GetCandListByManagerCall.workerfname(candidate).toString(), lname: GetCandListByManagerCall.workerlname(candidate).toString(), dateEvent: GetCandListByManagerCall.dateEvent(candidate).toString(), ), ); }, );
额外建议
- 为候选人创建数据模型类,通过
json_serializable解析API响应,避免直接操作动态类型,提升代码可读性和安全性。 - 添加错误捕获逻辑,处理API响应解析失败的情况。
内容的提问来源于stack exchange,提问作者Shon22
相关产品推荐
相关产品推荐

