如何从PokeApi获取进化链数据并简化处理适配Flutter应用
Flutter 处理 PokeApi 进化链嵌套 JSON 方案
核心思路:把递归嵌套的原始JSON转换为自用的Dart结构化模型,只保留业务需要的字段,避免后续每次取值都要多层索引嵌套。
1. 定义可递归的Dart数据模型
不用映射原始JSON的全部字段,仅保留展示需要的内容即可,比如宝可梦名称、接口地址、最低进化等级、后续进化节点:
class EvolutionNode { // 当前阶段宝可梦基础信息 final String pokemonName; final String pokemonId; // 提前提取宝可梦id,方便后续加载资源 // 进化触发条件,可根据需要扩展道具、亲密度等字段 final int? minEvolveLevel; // 后续进化节点,支持多分支进化场景 final List<EvolutionNode> nextEvolutions; EvolutionNode({ required this.pokemonName, required this.pokemonId, this.minEvolveLevel, required this.nextEvolutions, }); // 递归解析JSON的工厂方法 factory EvolutionNode.fromJson(Map<String, dynamic> json) { // 解析当前节点宝可梦信息 final speciesUrl = json['species']['url'] as String; final pokemonId = speciesUrl.split('/').where((e) => e.isNotEmpty).last; // 解析进化条件 int? evolveLevel; if (json['evolution_details']?.isNotEmpty ?? false) { evolveLevel = json['evolution_details'][0]['min_level']; } // 递归解析后续进化节点 List<EvolutionNode> nextNodes = []; if (json['evolves_to']?.isNotEmpty ?? false) { nextNodes = json['evolves_to'] .map<EvolutionNode>((childJson) => EvolutionNode.fromJson(childJson)) .toList(); } return EvolutionNode( pokemonName: json['species']['name'], pokemonId: pokemonId, minEvolveLevel: evolveLevel, nextEvolutions: nextNodes, ); } // 工具方法:如果是单链进化,可直接展开为一维列表,适配ListView展示 List<EvolutionNode> flattenToList() { final list = [this]; for (final node in nextEvolutions) { list.addAll(node.flattenToList()); } return list; } }
2. 接口请求&解析示例
import 'package:http/http.dart' as http; import 'dart:convert'; // 请求&解析调用代码 Future<EvolutionNode> getEvolutionChain() async { final res = await http.get(Uri.parse('https://pokeapi.co/api/v2/evolution-chain/67/')); final rawData = jsonDecode(res.body); // 直接传入原始JSON的chain字段即可完成全链路解析 return EvolutionNode.fromJson(rawData['chain']); }
优化建议
- 如果只需要展示单进化链,解析完成后直接调用
flattenToList()得到一维数组,后续UI层无需处理任何嵌套逻辑,直接按索引取值即可 - 多分支进化场景(如伊布)保留树结构即可,可直接适配树形UI组件
- 不需要的字段直接忽略即可,无需全部解析,能大幅减少模型复杂度
内容的提问来源于stack exchange,提问作者dipansh
相关产品推荐
相关产品推荐

