如何在Flutter项目中实现省市二级联动下拉选择菜单?
Flutter 二级省市联动下拉菜单实现方案
实现思路
通过两个DropdownButton组件实现联动:选中省份后,动态更新城市下拉菜单的选项列表,核心是通过状态管理切换数据源。
完整实现代码
import 'package:flutter/material.dart'; class ProvinceCityDropdown extends StatefulWidget { const ProvinceCityDropdown({super.key}); @override State<ProvinceCityDropdown> createState() => _ProvinceCityDropdownState(); } class _ProvinceCityDropdownState extends State<ProvinceCityDropdown> { // 模拟省市数据源,实际项目可替换为接口请求 final List<Map<String, dynamic>> _provinceData = [ { "name": "北京市", "cities": ["东城区", "西城区", "朝阳区", "海淀区"] }, { "name": "上海市", "cities": ["黄浦区", "徐汇区", "长宁区", "静安区"] }, { "name": "广东省", "cities": ["广州市", "深圳市", "佛山市", "东莞市"] }, ]; String? _selectedProvince; List<String> _cityList = []; String? _selectedCity; @override void initState() { super.initState(); // 初始化默认加载第一个省份的城市 if (_provinceData.isNotEmpty) { _selectedProvince = _provinceData[0]["name"]; _cityList = List<String>.from(_provinceData[0]["cities"]); } } // 根据选中的省份更新城市列表 void _updateCityList(String provinceName) { final targetProvince = _provinceData.firstWhere((p) => p["name"] == provinceName); setState(() { _cityList = List<String>.from(targetProvince["cities"]); _selectedCity = null; // 切换省份后清空已选城市,避免数据不匹配 }); } @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // 省份下拉菜单 Container( width: 120, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(6), ), child: DropdownButtonHideUnderline( child: DropdownButton<String>( value: _selectedProvince, isExpanded: true, hint: const Text("选择省份"), items: _provinceData.map((province) { return DropdownMenuItem( value: province["name"], child: Text(province["name"]), ); }).toList(), onChanged: (value) { if (value != null) { setState(() => _selectedProvince = value); _updateCityList(value); } }, ), ), ), const SizedBox(width: 16), // 城市下拉菜单 Container( width: 120, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(6), ), child: DropdownButtonHideUnderline( child: DropdownButton<String>( value: _selectedCity, isExpanded: true, hint: const Text("选择城市"), items: _cityList.map((city) { return DropdownMenuItem( value: city, child: Text(city), ); }).toList(), onChanged: (value) => setState(() => _selectedCity = value), ), ), ), ], ); } } // 调用示例 void main() { runApp(const MaterialApp( home: Scaffold( body: Center(child: ProvinceCityDropdown()), ), )); }
扩展说明
- 数据源可替换为接口请求:如果省市数据来自后端,可在
initState或用户触发时发起网络请求,更新_provinceData - 样式自定义:可根据项目UI规范调整下拉菜单的边框、背景色、文字样式等
- 空状态处理:可添加判断逻辑,在数据源为空时显示提示文本
内容的提问来源于stack exchange,提问作者Nikunj Panchal
相关产品推荐
相关产品推荐

