如何将服务端动态JSON转为Dart模型并实现可点击取ID的可展开ListView
实现方案
步骤1:定义数据模型
首先创建对应的Dart实体类:
class Categories { // 一级分类名称 final String categoryName; // 二级子分类名称列表 final List<String> subCategoryNames; // 子分类对应产品ID列表,和子分类名称下标一一对应 final List<int> productIds; Categories(this.categoryName, this.subCategoryNames, this.productIds); }
步骤2:JSON转换为目标数据结构
拿到服务端返回的JSON并解码后,按如下逻辑转换为你需要的结构:
// 此处为服务端返回解码后的Map数据,可根据你项目的网络请求逻辑替换 Map<String, dynamic> serverResponse = /* 网络请求拿到的解码JSON */; Map<String, dynamic> rawCategoryData = serverResponse['data']; List<Categories> categories = []; // 遍历一级分类 rawCategoryData.forEach((categoryName, subList) { List<String> subNames = []; List<int> ids = []; // 遍历当前一级分类下的所有子分类 for (var subItem in subList) { Map<String, dynamic> subMap = subItem as Map<String, dynamic>; // 每个子分类是单键值对的Map,分别取出名称和ID String subName = subMap.keys.first; int productId = subMap.values.first; subNames.add(subName); ids.add(productId); } categories.add(Categories(categoryName, subNames, ids)); });
如果需要兼容空值异常,可以在遍历前增加对应判空逻辑。
步骤3:实现可展开列表,点击子项获取产品ID
使用Flutter自带的ExpansionTile组件即可快速实现需求:
ListView.builder( itemCount: categories.length, itemBuilder: (context, index) { final currentCategory = categories[index]; return ExpansionTile( title: Text(currentCategory.categoryName), // 展开后的子项列表 children: List.generate(currentCategory.subCategoryNames.length, (subIndex) { final subName = currentCategory.subCategoryNames[subIndex]; // 子分类下标和产品ID下标一一对应,直接取出即可 final targetProductId = currentCategory.productIds[subIndex]; return ListTile( title: Text(subName), onTap: () { // 此处已经拿到对应产品ID,可直接处理业务逻辑 debugPrint('选中的产品ID为:$targetProductId'); }, ); }), ); }, )
如果需要更复杂的展开效果、动画或者自定义样式,也可以自行封装扩展组件,核心逻辑和上述实现一致。
内容的提问来源于stack exchange,提问作者Unknown
相关产品推荐
相关产品推荐

