Flutter中基于JSON数据实现三级联动下拉菜单的技术求助
实现Flutter关联下拉菜单(基于Bloc和PizzaEntity)
作为Flutter初学者,我现有如下JSON响应数据:
{ "pizza":[ { "type":"auto", "name":"bmw", "currency":"usd" }, { "type":"furniture", "name":"closet", "currency":"eur" }, { "type":"electronics", "name":"PC", "currency":"GBP" }, { "type":"auto", "name":"audi", "currency":"GBP" } ] }
数据已映射至PizzaEntity实体类:
class PizzaEntity extends Equatable { final String type; final String name; final String currency; const PizzaEntity({ required this.type, required this.name, required this.currency, }); @override List<Object?> get props => [ type, name, currency, ]; }
现有UI代码片段:
BlocBuilder<MyBlocBloc, MyBlocState>( builder: (context, state) { if (state is MyBlocLoading) { return const Center( child: CircularProgressIndicator(), ); } else if (state is MyBlocLoaded) { // 修正:原代码类型错误,此处应为List<PizzaEntity> List<PizzaEntity> pizzas = state.pizza; if (pizzas.isEmpty) { return const Text("暂无数据"); } return // 需在此处添加三个关联下拉菜单 } else if (state is MyBlocError) { return const Text("加载失败"); } else { return const Center( child: Icon(Icons.error), ); } } )
需要添加三个关联的下拉菜单:
- 类型下拉菜单(如auto);
- 关联选中类型的名称下拉菜单(如选中auto时显示bmw、audi);
- 关联选中类型和名称的货币下拉菜单(如选中bmw时显示usd,选中audi时显示GBP)。
具体实现代码
将上述代码中return // 需在此处添加三个关联下拉菜单的位置替换为以下代码,通过StatefulBuilder管理临时选中状态实现下拉联动:
return StatefulBuilder( builder: (context, setState) { String? selectedType; String? selectedName; String? selectedCurrency; // 获取去重的所有类型选项 final types = pizzas.map((e) => e.type).toSet().toList(); // 根据选中类型过滤名称选项 final names = selectedType != null ? pizzas.where((e) => e.type == selectedType).map((e) => e.name).toSet().toList() : []; // 根据选中类型和名称过滤货币选项 final currencies = selectedType != null && selectedName != null ? pizzas.where((e) => e.type == selectedType && e.name == selectedName).map((e) => e.currency).toSet().toList() : []; return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 类型下拉菜单 DropdownButton<String>( hint: const Text("选择类型"), value: selectedType, items: types.map((type) { return DropdownMenuItem( value: type, child: Text(type), ); }).toList(), onChanged: (value) { setState(() { selectedType = value; // 切换类型时重置名称和货币选中值 selectedName = null; selectedCurrency = null; }); }, ), const SizedBox(height: 16), // 名称下拉菜单(关联类型) DropdownButton<String>( hint: const Text("选择名称"), value: selectedName, items: names.map((name) { return DropdownMenuItem( value: name, child: Text(name), ); }).toList(), onChanged: selectedType != null ? (value) { setState(() { selectedName = value; // 切换名称时重置货币选中值 selectedCurrency = null; }); } : null, enabled: selectedType != null, ), const SizedBox(height: 16), // 货币下拉菜单(关联类型和名称) DropdownButton<String>( hint: const Text("选择货币"), value: selectedCurrency, items: currencies.map((currency) { return DropdownMenuItem( value: currency, child: Text(currency), ); }).toList(), onChanged: (selectedType != null && selectedName != null) ? (value) { setState(() { selectedCurrency = value; }); } : null, enabled: selectedType != null && selectedName != null, ), ], ); }, );
代码说明
- 状态管理:用
StatefulBuilder在BlocBuilder内部临时维护下拉选中状态,避免把UI临时状态混入Bloc全局状态(若需全局保存选中值,可将状态移入Bloc)。 - 选项过滤:
- 类型选项:从所有实体中提取去重的
type; - 名称选项:根据选中的
type过滤对应name并去重; - 货币选项:根据选中的
type和name过滤对应currency;
- 类型选项:从所有实体中提取去重的
- 联动逻辑:切换类型时重置名称和货币选中值,切换名称时重置货币选中值,确保下拉选项始终与当前选中状态匹配。
内容的提问来源于stack exchange,提问作者Leilin
相关产品推荐
相关产品推荐

