Flutter开发:根据DropdownButton选择结果渲染组件列表
解决Flutter中根据下拉选择渲染对应菜品列表的问题
需求说明
根据下拉框选择的Veg/Non Veg/Both选项,从给定的映射列表中筛选对应菜品,在指定位置渲染包含餐厅名称和菜品名称的组件列表。
解决方案步骤
- 添加筛选逻辑:根据当前下拉选中值,过滤出符合条件的菜品数据
- 构建菜品项组件:创建展示餐厅和菜品信息的UI单元
- 渲染筛选后的列表:在指定位置动态生成菜品列表
修改后的完整代码
class _MyAppState extends State<MyApp> { bool _somethingEntered = false; String _dropDownValue = ""; late String _enteredInput; List<Map<String, dynamic>> list = [ {"eatery": "Yummpies", "Veg": true, "Name": "Veg Fried Rice"}, {"eatery": "Yummpies", "Veg": false, "Name": "Chicken Fried Rice"}, {"eatery": "BitsAndBytes", "Veg": true, "Name": "Veg Roll"} ]; void dropDownCallback(String? selectedValue) { if (selectedValue is String) { setState(() { _dropDownValue = selectedValue; }); } } // 筛选符合条件的菜品列表 List<Map<String, dynamic>> _getFilteredDishes() { switch (_dropDownValue) { case "Veg": return list.where((dish) => dish["Veg"] == true).toList(); case "Non Veg": return list.where((dish) => dish["Veg"] == false).toList(); case "Both": return list; default: return []; } } // 单个菜品项组件 Widget _buildDishItem(Map<String, dynamic> dish) { return Container( margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( dish["eatery"], style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( dish["Name"], style: const TextStyle(fontSize: 14), ), ], ), ); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: const Text("Find Your Food"), centerTitle: true, backgroundColor: Colors.orange[600], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Center( child: ColoredBox( color: Colors.amber, child: SizedBox( height: 400, width: 400, child: Column( children: [ Padding( padding: const EdgeInsets.all(10.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( color: Colors.white, child: TextField( decoration: const InputDecoration( hintText: "Enter Your Requirements Here", contentPadding: EdgeInsets.symmetric( horizontal: 10.0, vertical: 5.0), ), ), ), const SizedBox(height: 10.0), Container( color: Colors.blue, child: ElevatedButton( onPressed: () { print("pressed!"); }, child: const Icon(Icons.local_pizza), ), ), DropdownButton( value: _dropDownValue.isEmpty ? null : _dropDownValue, hint: const Text("Select Category"), onChanged: dropDownCallback, items: const [ DropdownMenuItem( child: Text("Veg"), value: "Veg", ), DropdownMenuItem( child: Text("Non Veg"), value: "Non Veg", ), DropdownMenuItem( child: Text('Both'), value: "Both", ) ], ), // 渲染菜品列表的位置 Expanded( child: ListView.builder( shrinkWrap: true, itemCount: _getFilteredDishes().length, itemBuilder: (context, index) { return _buildDishItem(_getFilteredDishes()[index]); }, ), ) ], ), ), ], ), ), ), ), ), ), ); } }
关键修改说明
- 筛选函数
_getFilteredDishes:通过switch判断下拉选中值,返回对应筛选后的菜品列表 - 菜品项组件
_buildDishItem:封装单个菜品的UI展示,包含餐厅名和菜品名,添加基础样式提升可读性 - 列表渲染:使用
ListView.builder替代静态Column,配合shrinkWrap: true避免固定高度容器中出现溢出问题;用Expanded让列表占据剩余空间 - 下拉框优化:添加
hint提示文本,设置value让下拉框显示当前选中值,提升用户体验
内容的提问来源于stack exchange,提问作者DaObliterator
相关产品推荐
相关产品推荐

