flutter如何实现省市区选择

在Flutter项目中需要实现省市区三级联动选择功能,应该使用什么方案比较合适?目前看到有picker和cascader两种组件方案,但不太清楚具体实现细节。请问:

  1. 如何获取并解析全国的省市区数据?
  2. 是否有现成的第三方库推荐?
  3. 实现这种级联选择器需要注意哪些性能问题?
  4. 在UI展示上有什么最佳实践或设计规范吗?
2 回复

在Flutter中实现省市区选择,可使用第三方库如city_pickersflutter_picker。通过showModalBottomSheet弹出选择器,传入省市区数据(JSON格式),监听选择结果并更新状态即可。

更多关于flutter如何实现省市区选择的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现省市区选择,可以通过以下几种方式:

1. 使用第三方库(推荐)

cascadia_picker 库

dependencies:
  cascadia_picker: ^1.0.0
import 'package:cascadia_picker/cascadia_picker.dart';

// 使用示例
void _showCityPicker() async {
  final result = await showCascadiaPicker(
    context: context,
    data: cascadiaData, // 内置的中国省市区数据
  );
  
  if (result != null) {
    print('选择结果: ${result.provinceName} - ${result.cityName} - ${result.areaName}');
  }
}

city_pickers 库

dependencies:
  city_pickers: ^1.0.0
import 'package:city_pickers/city_pickers.dart';

void _showCityPicker() async {
  final result = await CityPickers.showCityPicker(
    context: context,
  );
  
  if (result != null) {
    print('${result.provinceName} ${result.cityName} ${result.areaName}');
  }
}

2. 自定义实现

数据准备

class AreaModel {
  final String code;
  final String name;
  final List<AreaModel>? children;
  
  AreaModel({required this.code, required this.name, this.children});
}

// 示例数据结构
List<AreaModel> provinces = [
  AreaModel(
    code: '11',
    name: '北京市',
    children: [
      AreaModel(
        code: '1101',
        name: '市辖区',
        children: [
          AreaModel(code: '110101', name: '东城区'),
          AreaModel(code: '110102', name: '西城区'),
        ],
      ),
    ],
  ),
  // 其他省份...
];

自定义选择器

class CityPicker extends StatefulWidget {
  @override
  _CityPickerState createState() => _CityPickerState();
}

class _CityPickerState extends State<CityPicker> {
  List<AreaModel> currentList = [];
  AreaModel? selectedProvince;
  AreaModel? selectedCity;
  AreaModel? selectedArea;

  @override
  void initState() {
    super.initState();
    currentList = provinces;
  }

  void _onItemSelected(AreaModel area, int level) {
    setState(() {
      switch (level) {
        case 0:
          selectedProvince = area;
          selectedCity = null;
          selectedArea = null;
          currentList = area.children ?? [];
          break;
        case 1:
          selectedCity = area;
          selectedArea = null;
          currentList = area.children ?? [];
          break;
        case 2:
          selectedArea = area;
          // 选择完成
          Navigator.pop(context, {
            'province': selectedProvince,
            'city': selectedCity,
            'area': selectedArea,
          });
          break;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('选择地区')),
      body: Row(
        children: [
          // 省份列表
          Expanded(
            child: ListView.builder(
              itemCount: provinces.length,
              itemBuilder: (context, index) => ListTile(
                title: Text(provinces[index].name),
                onTap: () => _onItemSelected(provinces[index], 0),
              ),
            ),
          ),
          // 城市列表
          if (selectedProvince != null)
            Expanded(
              child: ListView.builder(
                itemCount: currentList.length,
                itemBuilder: (context, index) => ListTile(
                  title: Text(currentList[index].name),
                  onTap: () => _onItemSelected(currentList[index], 1),
                ),
              ),
            ),
          // 区域列表
          if (selectedCity != null)
            Expanded(
              child: ListView.builder(
                itemCount: currentList.length,
                itemBuilder: (context, index) => ListTile(
                  title: Text(currentList[index].name),
                  onTap: () => _onItemSelected(currentList[index], 2),
                ),
              ),
            ),
        ],
      ),
    );
  }
}

推荐方案

对于大多数应用场景,推荐使用第三方库 city_pickerscascadia_picker,它们提供了:

  • 完整的中国省市区数据
  • 美观的UI界面
  • 简单的API调用
  • 良好的性能优化

选择哪种方案取决于你的具体需求:如果需要快速实现且UI要求不高,使用第三方库;如果需要完全自定义UI和交互逻辑,可以选择自定义实现。

回到顶部