taiwan_city_picker 1.0.5
taiwan_city_picker: ^1.0.5 copied to clipboard
A Flutter widget for Taiwan city and district picker.
import 'package:flutter/material.dart';
import 'package:taiwan_city_picker/taiwan_city_picker.dart';
void main() {
runApp(DemoPage());
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
final TaiwanCityPickerController _controllerController =
TaiwanCityPickerController();
@override
void dispose() {
_controllerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Taiwan City Picker Demo',
home: Scaffold(
appBar: AppBar(title: Text('Taiwan City Picker Demo')),
body: Center(
child: SingleChildScrollView(
padding: EdgeInsets.all(16.0),
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 500),
child: Column(
spacing: 80,
children: [
_item(
'Horizontal (水平 Layout)',
TaiwanCityPicker(onChange: onChange),
),
_item(
'Vertical (垂直 Layout)',
TaiwanCityPicker(
layoutDirection: LayoutDirection.vertical,
onChange: onChange,
),
),
_item(
'Custom Border (框線設定)',
TaiwanCityPicker(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.blue, width: 2),
),
onChange: onChange,
),
),
_item(
'Location Sorting (距離由近到遠排序)',
TaiwanCityPicker(
latitude: 24.0541621,
longitude: 120.6478417,
onChange: onChange,
),
),
_item(
'Whitelist Zip Code (只顯示樹林、龜山)',
TaiwanCityPicker(
whitelistZipCode: [238, 333],
onChange: onChange,
),
),
_item(
'Blacklist County (不顯示外島縣市)',
TaiwanCityPicker(
blacklistCountyCode: ['09007', '10016', '09020'],
onChange: onChange,
),
),
_item(
'Variant Chinese characters (異體字)',
TaiwanCityPicker(
defaultZipCode: 950,
stdWord: false,
onChange: onChange,
),
),
_item(
'Default County Code (預設臺中市)',
TaiwanCityPicker(
defaultCountyCode: '66000',
onChange: onChange,
),
),
_item(
'Default Zip Code (預設信義區 110)',
TaiwanCityPicker(defaultZipCode: 110, onChange: onChange),
),
_item(
'Searchable Mode',
TaiwanCityPicker(searchable: true, onChange: onChange),
),
_item(
'Controller Methods (控制器操作)',
TaiwanCityPicker(
controller: _controllerController,
onChange: onChange,
),
Padding(
padding: EdgeInsets.only(top: 8),
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton(
onPressed: () =>
_controllerController.setCountyCode('64000'),
child: Text('設定高雄市'),
),
ElevatedButton(
onPressed: () =>
_controllerController.setZipCode(238),
child: Text('設定樹林區'),
),
ElevatedButton(
onPressed: () => _controllerController.reset(),
child: Text('清空'),
),
],
),
),
),
_item(
'English Mode (英文)',
TaiwanCityPicker(
layoutDirection: LayoutDirection.vertical,
language: Language.enUS,
onChange: onChange,
showZipCode: true,
),
),
_item(
'Only County (只需要縣市選擇)',
TaiwanCityPicker(onlyCounty: true, onChange: onChange),
),
_item(
'Costom Builder (自訂樣式 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],
),
),
);
},
),
),
_item(
'Costom Builder (自訂樣式 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: SizedBox(
width: 50,
child: Text(
county.countyName,
style: TextStyle(fontSize: 12),
textAlign: TextAlign.center,
),
),
);
}).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: onChange,
),
),
],
),
),
),
),
),
);
}
void onChange(
ChangeType changeType,
SelectedCounty? county,
SelectedDistrict? district,
) {
print('>>>>>>>>>=============================');
print('changeType: $changeType');
print('county: $county');
print('district: $district');
print('=============================<<<<<<<<<');
}
Widget _item(String title, TaiwanCityPicker child, [Widget? other]) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(bottom: 16),
child: Text(title, style: TextStyle(fontSize: 18)),
),
child,
if (other != null) other,
],
);
}
}