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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:53:25