You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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!;
                });
              }),
          //
        ],
      ),
    );
  }
}

问题分析与修复

核心问题点

  1. 存在未定义变量(dataset、onCarModelChanged、selectedMake),导致编译报错
  2. 下拉菜单泛型类型与选中值类型不匹配(DropdownButton<String?>绑定FloorModel实例)
  3. 未实现根据楼层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;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

修复说明

  1. 变量规范:将选中状态变量移至State类内部,移除未定义的无效变量
  2. 类型匹配:下拉菜单泛型与绑定值类型统一(DropdownButton<FloorModel>和DropdownButton<HallModel?>)
  3. 过滤逻辑:通过计算属性_filteredHalls,使用where方法筛选与当前楼层shortname匹配的Hall
  4. 状态同步:切换楼层时调用setState更新UI,并自动重置选中的大厅
  5. UI优化:改用Column布局避免组件溢出,添加大厅下拉框提示文本

内容的提问来源于stack exchange,提问作者Chamithu Dinsara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:27:23