Flutter中基于Model的联动下拉菜单异常问题求助
Flutter楼层与大厅联动问题修复方案
问题场景
选中特定楼层时,系统需加载对应楼层图片,以及与该楼层floorshortname匹配的Hall列表,但当前实现代码无法正常运行。
现有模型代码
FloorModel
class FloorModel { final int id; final String floorname; final String floorimg; final String floorshortname; FloorModel(this.id, this.floorname, this.floorimg, this.floorshortname); }
HallModel
class HallModel { final int id; final String hallname; final String hallpoint; final String hallshortname; HallModel(this.id, this.hallname, this.hallpoint, this.hallshortname); }
问题代码(FOCMap组件)
import 'package:flutter/material.dart'; import '../../models/FloorModel.dart'; import '../../models/HallModel.dart'; class FOCMap extends StatefulWidget { const FOCMap({super.key}); @override State<FOCMap> createState() => _FOCMapState(); } List<FloorModel> floorlist = [ FloorModel(1, 'Ground Floor', 'img/groundfloor.jpg', 'ground'), FloorModel(2, '1st floor', 'img/first.jpeg', 'first'), FloorModel(3, '2nd Floor', 'img/second.jpeg', 'second'), FloorModel(4, 'B1 Floor', 'img/b1.jpeg', 'BOne'), FloorModel(5, 'B2 Floor', 'img/b2.jpeg', 'BTwo'), FloorModel(6, 'B3 Floor', 'img/b3.jpeg', 'BThree'), ]; List<HallModel> halllist = [ HallModel(1, '001', 'img/groundfloor.jpg', 'ground'), HallModel(2, '002', 'img/first.jpeg', 'first'), HallModel(3, '003', 'img/second.jpeg', 'second'), HallModel(4, '101', 'img/second.jpeg', 'BOne'), HallModel(5, 'Admin', 'img/second.jpeg', 'BTwo'), HallModel(6, 'office', 'img/second.jpeg', 'BThree'), ]; FloorModel _selectedfloorModel = floorlist.first; HallModel _selectedhallModel = halllist.first; class _FOCMapState extends State<FOCMap> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Faculty of Computing"), actions: <Widget>[ IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), ], ), body: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( image: DecorationImage( image: AssetImage(_selectedfloorModel.floorimg), fit: BoxFit.cover, ) ), children: [ DropdownButton<String?>( value: _selectedfloorModel, items: dataset.keys.map((e) { return DropdownMenuItem<String?>( value: e, child: Text('$e'), ); }).toList(), onChanged: onCarModelChanged), const SizedBox( height: 10, ), DropdownButton<String?>( value: selectedMake, items: (dataset[_selectedfloorModel] ?? []).map((e) { return DropdownMenuItem<String?>( value: e, child: Text('$e'), ); }).toList(), onChanged: (val) { setState(() { selectedMake = val!; }); }), // ], ), ); } }
问题分析与修复
核心问题点
- 存在未定义变量(
dataset、onCarModelChanged、selectedMake),导致编译报错 - 下拉菜单泛型类型与选中值类型不匹配(
DropdownButton<String?>绑定FloorModel实例) - 未实现根据楼层
shortname过滤Hall列表的逻辑
修复后的完整代码
import 'package:flutter/material.dart'; import '../../models/FloorModel.dart'; import '../../models/HallModel.dart'; class FOCMap extends StatefulWidget { const FOCMap({super.key}); @override State<FOCMap> createState() => _FOCMapState(); } List<FloorModel> floorlist = [ FloorModel(1, 'Ground Floor', 'img/groundfloor.jpg', 'ground'), FloorModel(2, '1st floor', 'img/first.jpeg', 'first'), FloorModel(3, '2nd Floor', 'img/second.jpeg', 'second'), FloorModel(4, 'B1 Floor', 'img/b1.jpeg', 'BOne'), FloorModel(5, 'B2 Floor', 'img/b2.jpeg', 'BTwo'), FloorModel(6, 'B3 Floor', 'img/b3.jpeg', 'BThree'), ]; List<HallModel> halllist = [ HallModel(1, '001', 'img/groundfloor.jpg', 'ground'), HallModel(2, '002', 'img/first.jpeg', 'first'), HallModel(3, '003', 'img/second.jpeg', 'second'), HallModel(4, '101', 'img/second.jpeg', 'BOne'), HallModel(5, 'Admin', 'img/second.jpeg', 'BTwo'), HallModel(6, 'office', 'img/second.jpeg', 'BThree'), ]; class _FOCMapState extends State<FOCMap> { // 选中的楼层实例 FloorModel _selectedFloor = floorlist.first; // 选中的大厅实例 HallModel? _selectedHall; // 根据选中楼层过滤匹配的大厅列表 List<HallModel> get _filteredHalls { return halllist.where((hall) => hall.hallshortname == _selectedFloor.floorshortname).toList(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Faculty of Computing"), actions: <Widget>[ IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), ], ), body: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( image: DecorationImage( image: AssetImage(_selectedFloor.floorimg), fit: BoxFit.cover, ), ), child: Column( children: [ // 楼层选择下拉框 DropdownButton<FloorModel>( value: _selectedFloor, items: floorlist.map((floor) { return DropdownMenuItem<FloorModel>( value: floor, child: Text(floor.floorname), ); }).toList(), onChanged: (FloorModel? newFloor) { if (newFloor != null) { setState(() { _selectedFloor = newFloor; // 切换楼层时重置选中的大厅 _selectedHall = _filteredHalls.isNotEmpty ? _filteredHalls.first : null; }); } }, ), const SizedBox(height: 10), // 大厅选择下拉框 DropdownButton<HallModel?>( value: _selectedHall, hint: const Text("选择大厅"), items: _filteredHalls.map((hall) { return DropdownMenuItem<HallModel>( value: hall, child: Text(hall.hallname), ); }).toList(), onChanged: (HallModel? newHall) { setState(() { _selectedHall = newHall; }); }, ), ], ), ), ); } }
修复说明
- 变量规范:将选中状态变量移至State类内部,移除未定义的无效变量
- 类型匹配:下拉菜单泛型与绑定值类型统一(
DropdownButton<FloorModel>和DropdownButton<HallModel?>) - 过滤逻辑:通过计算属性
_filteredHalls,使用where方法筛选与当前楼层shortname匹配的Hall - 状态同步:切换楼层时调用
setState更新UI,并自动重置选中的大厅 - UI优化:改用
Column布局避免组件溢出,添加大厅下拉框提示文本
内容的提问来源于stack exchange,提问作者Chamithu Dinsara
相关产品推荐
相关产品推荐

