Taiwan City Picker
台灣縣市選擇器,可以自訂樣式。 Web Demo
Features
- 設定座標由近到遠顯示
- 縣市區黑名單、白名單控制顯示
- 大小寫臺、台切換
- 選項顯示郵遞區號
- 英文語系
- 文字輸入搜尋
- 框線樣式設定
- 水平和垂直佈局
- 自訂 Builder
- 提供 Controller 控制器
Options
基本設定
| Option |
Description |
Type |
Default |
controller |
控制選擇狀態 |
TaiwanCityPickerController? |
null |
onChange |
選擇變更時的 Callback Function |
Function? |
null |
countyHint |
縣市選擇器的提示文字 |
String? |
null |
districtHint |
地區選擇器的提示文字 |
String? |
null |
onlyCounty |
是否只顯示縣市選擇器 |
bool |
false |
Layout
| Option |
Description |
Type |
Default |
layoutDirection |
Layout 方向 |
LayoutDirection |
horizontal |
mainAxisAlignment |
主軸對齊方式 |
MainAxisAlignment |
start |
crossAxisAlignment |
副軸對齊方式 |
CrossAxisAlignment |
center |
mainAxisSize |
主軸大小 |
MainAxisSize |
max |
spacing |
縣市和地區選擇器之間的間距 |
double |
12.0 |
Style
| Option |
Description |
Type |
Default |
border |
輸入框邊框樣式 |
InputBorder? |
null |
menuHeight |
下拉選單的最大高度 |
double |
200.0 |
功能設定
| Option |
Description |
Type |
Default |
searchable |
是否啟用搜尋功能 |
bool |
false |
language |
顯示語言(中文/英文) |
Language |
zhTW |
showZipCode |
是否在地區名稱前顯示郵遞區號 |
bool |
false |
stdWord |
是否使用標準字(true: 臺,false: 台) |
bool |
true |
Location
| Option |
Description |
Type |
Default |
latitude |
參考點緯度(用於距離排序) |
double? |
null |
longitude |
參考點經度(用於距離排序) |
double? |
null |
Filter
| Option |
Description |
Type |
Default |
whitelistCountyCode |
縣市代碼白名單 |
List<String>? |
null |
blacklistCountyCode |
縣市代碼黑名單 |
List<String>? |
null |
whitelistZipCode |
郵遞區號白名單 |
List<int>? |
null |
blacklistZipCode |
郵遞區號黑名單 |
List<int>? |
null |
Default Value
| Option |
Description |
Type |
Default |
defaultCountyCode |
預設選擇的縣市代碼 |
String? |
null |
defaultZipCode |
預設選擇的郵遞區號 |
int? |
null |
Custom UI Builder
| Option |
Description |
Type |
Default |
countyBuilder |
自訂縣市選擇器 UI |
CountyBuilder? |
null |
districtBuilder |
自訂地區選擇器 UI |
DistrictBuilder? |
null |
layoutBuilder |
自訂整體佈局 |
LayoutBuilder? |
null |
County Code 對照表
| County |
Code |
| 臺北市 |
63000 |
| 基隆市 |
10017 |
| 新北市 |
65000 |
| 連江縣 |
09007 |
| 宜蘭縣 |
10002 |
| 新竹市 |
10018 |
| 新竹縣 |
10004 |
| 桃園市 |
68000 |
| 苗栗縣 |
10005 |
| 臺中市 |
66000 |
| 彰化縣 |
10007 |
| 南投縣 |
10008 |
| 嘉義市 |
10020 |
| 嘉義縣 |
10010 |
| 雲林縣 |
10009 |
| 臺南市 |
67000 |
| 高雄市 |
64000 |
| 澎湖縣 |
10016 |
| 金門縣 |
09020 |
| 屏東縣 |
10013 |
| 臺東縣 |
10014 |
| 花蓮縣 |
10015 |
使用範例
基本使用
TaiwanCityPicker(
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {
print('changeType: $changeType');
print('county: $county');
print('district: $district');
},
)
Vertical (垂直 Layout)
TaiwanCityPicker(
layoutDirection: LayoutDirection.vertical,
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Custom Border (框線設定)
TaiwanCityPicker(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.blue, width: 2),
),
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Location Sorting (距離由近到遠排序)
TaiwanCityPicker(
latitude: 24.0541621, // 台中市緯度
longitude: 120.6478417, // 台中市經度
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Whitelist Zip Code (只顯示樹林、龜山)
TaiwanCityPicker(
whitelistZipCode: [238, 333], // 樹林區、龜山區
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Blacklist County (不顯示外島縣市)
TaiwanCityPicker(
blacklistCountyCode: ['09007', '10016', '09020'], // 金門、連江、澎湖
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Variant Chinese characters (異體字)
TaiwanCityPicker(
defaultZipCode: 950,
stdWord: false,
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Default County Code (預設臺中市)
TaiwanCityPicker(
defaultCountyCode: '66000', // 臺中市代碼
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Default Zip Code (預設信義區 110)
TaiwanCityPicker(
defaultZipCode: 110, // 信義區郵遞區號
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Searchable Mode
TaiwanCityPicker(
searchable: true, // 啟用搜尋功能
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Controller Methods (控制器操作)
final TaiwanCityPickerController controller = TaiwanCityPickerController();
TaiwanCityPicker(
controller: controller,
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
ElevatedButton(
onPressed: () => controller.setCountyCode('64000'),
child: Text('設定高雄市'),
),
ElevatedButton(
onPressed: () => controller.setZipCode(238),
child: Text('設定樹林區'),
),
ElevatedButton(
onPressed: () => controller.reset(),
child: Text('清空'),
),
English Mode (英文)
TaiwanCityPicker(
layoutDirection: LayoutDirection.vertical,
language: Language.enUS,
showZipCode: true,
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Only County (只需要縣市選擇)
TaiwanCityPicker(
onlyCounty: true,
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
Custom Builder 1 (自訂樣式 1)
TaiwanCityPicker(
countyBuilder:
(
BuildContext context,
List<TaiwanCityModel> counties,
TaiwanCityModel? selectedCounty,
void Function(TaiwanCityModel?) onCountySelected,
String hintText,
) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.blue, Colors.lightBlue]),
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Padding(
padding: EdgeInsets.all(12),
child: Icon(Icons.location_city, color: Colors.white),
),
Expanded(
child: DropdownButton<TaiwanCityModel>(
value: selectedCounty,
hint: Text(hintText, style: TextStyle(color: Colors.white)),
isExpanded: true,
underline: SizedBox.shrink(),
dropdownColor: Colors.blue,
items: counties.map((county) {
return DropdownMenuItem<TaiwanCityModel>(
value: county,
child: Text(county.countyName, style: TextStyle(color: Colors.white)),
);
}).toList(),
onChanged: onCountySelected,
),
),
],
),
);
},
districtBuilder:
(
BuildContext context,
List<TaiwanCityModel> districts,
TaiwanCityModel? selectedDistrict,
void Function(TaiwanCityModel?)? onDistrictSelected,
String hintText,
bool enabled,
) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: enabled ? [Colors.green, Colors.lightGreen] : [Colors.grey.shade500, Colors.grey.shade500],
),
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Padding(
padding: EdgeInsets.all(12),
child: Icon(Icons.location_on, color: enabled ? Colors.white : Colors.grey.shade100),
),
Expanded(
child: DropdownButton<TaiwanCityModel>(
iconDisabledColor: Colors.grey.shade100,
value: selectedDistrict,
hint: Text(hintText, style: TextStyle(color: enabled ? Colors.white : Colors.grey.shade100)),
isExpanded: true,
underline: SizedBox.shrink(),
dropdownColor: Colors.green,
items: enabled
? districts
.map(
(district) => DropdownMenuItem<TaiwanCityModel>(
value: district,
child: Text('${district.townName} (${district.zipCode})', style: TextStyle(color: Colors.white)),
),
)
.toList()
: null,
onChanged: enabled ? onDistrictSelected : null,
),
),
],
),
);
},
layoutBuilder: (BuildContext context, Widget countyWidget, Widget districtWidget) {
return Card(
elevation: 3,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, spacing: 12, children: [countyWidget, districtWidget]),
),
);
},
)
Custom Builder 2 (自訂樣式 2)
TaiwanCityPicker(
defaultCountyCode: '63000',
countyBuilder:
(
BuildContext context,
List<TaiwanCityModel> counties,
TaiwanCityModel? selectedCounty,
void Function(TaiwanCityModel?) onCountySelected,
String hintText,
) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SegmentedButton<TaiwanCityModel>(
segments: counties.map((county) {
return ButtonSegment<TaiwanCityModel>(
value: county,
label: Text(county.countyName, style: TextStyle(fontSize: 12)),
);
}).toList(),
emptySelectionAllowed: true,
selected: selectedCounty != null ? {selectedCounty} : {},
onSelectionChanged: (Set<TaiwanCityModel> selection) {
onCountySelected(selection.isNotEmpty ? selection.first : null);
},
multiSelectionEnabled: false,
showSelectedIcon: false,
),
);
},
districtBuilder:
(
BuildContext context,
List<TaiwanCityModel> districts,
TaiwanCityModel? selectedDistrict,
void Function(TaiwanCityModel?)? onDistrictSelected,
String hintText,
bool enabled,
) {
return Expanded(
child: ListView(
children: districts.map((district) {
return RadioListTile<TaiwanCityModel>(
title: Text('(${district.zipCode}) ${district.townName}'),
value: district,
contentPadding: EdgeInsets.zero,
groupValue: selectedDistrict,
onChanged: enabled ? onDistrictSelected : null,
);
}).toList(),
),
);
},
layoutBuilder: (BuildContext context, Widget countyWidget, Widget districtWidget) {
return SizedBox(
height: 500,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [SizedBox(height: 8), countyWidget, SizedBox(height: 8), districtWidget],
),
);
},
onChange: (ChangeType changeType, SelectedCounty? county, SelectedDistrict? district) {},
)
資料來源
3碼郵遞區號與行政區地理座標對照KML