city_picker.dart 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:sport/widgets/city_picker_data.dart';
  5. Future<CityResult> showCityPicker(
  6. BuildContext context, {
  7. CityResult initCity,
  8. }) async {
  9. Completer<CityResult> completer = Completer();
  10. var cityData = await loadCityData();
  11. var result = showDialog(
  12. context: context,
  13. builder: (c) => CityPicker(
  14. params: cityData,
  15. initResult: initCity,
  16. ),
  17. );
  18. result.then((v) {
  19. completer.complete(v);
  20. });
  21. return completer.future;
  22. }
  23. class CityPicker extends StatefulWidget {
  24. final Map<String, dynamic> params;
  25. final CityResult initResult;
  26. const CityPicker({
  27. Key key,
  28. this.params,
  29. this.initResult,
  30. }) : super(key: key);
  31. @override
  32. _CityPickerState createState() => _CityPickerState();
  33. }
  34. class _CityPickerState extends State<CityPicker> {
  35. int provinceIndex = 0;
  36. int cityIndex = 0;
  37. int countyIndex = 0;
  38. var cityResult = CityResult();
  39. Map<String, dynamic> get datas => widget.params;
  40. List<dynamic> get provinceList => datas["provinceList"];
  41. String proviceNameByIndex(int index) => provinceList[index]["name"];
  42. List<dynamic> get cityList => provinceList[provinceIndex]["cityList"];
  43. List<dynamic> get countyList => cityList[cityIndex]["countyList"];
  44. FixedExtentScrollController provinceScrollController;
  45. FixedExtentScrollController cityScrollController;
  46. FixedExtentScrollController countyScrollController;
  47. @override
  48. void initState() {
  49. super.initState();
  50. var initResult = widget.initResult;
  51. List<int> initItems =
  52. findIndexs(initResult?.province, initResult?.city, initResult?.county);
  53. _log(initItems);
  54. provinceScrollController =
  55. FixedExtentScrollController(initialItem: initItems[0]);
  56. cityScrollController =
  57. FixedExtentScrollController(initialItem: initItems[1]);
  58. countyScrollController =
  59. FixedExtentScrollController(initialItem: initItems[2]);
  60. cityResult.province = proviceNameByIndex(0);
  61. cityResult.city = cityList[0]["name"];
  62. cityResult.county = countyList[0]["name"];
  63. provinceIndex = initItems[0];
  64. cityIndex = initItems[1];
  65. countyIndex = initItems[2];
  66. }
  67. @override
  68. void dispose() {
  69. provinceScrollController?.dispose();
  70. cityScrollController?.dispose();
  71. countyScrollController?.dispose();
  72. super.dispose();
  73. }
  74. String provinceByIndex(int index) {
  75. return provinceList[index]["name"];
  76. }
  77. @override
  78. Widget build(BuildContext context) {
  79. return AlertDialog(
  80. contentPadding: EdgeInsets.all(6.0),
  81. shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
  82. content: Container(
  83. width: 300,
  84. height: 200,
  85. child: Column(
  86. children: <Widget>[
  87. Row(
  88. children: <Widget>[
  89. IconButton(onPressed: () {
  90. Navigator.of(context).pop();
  91. }, icon: Text("取消")),
  92. Expanded(
  93. child: Center(
  94. child: Text(
  95. "选择地区",
  96. style: Theme.of(context).textTheme.headline3,
  97. ))),
  98. IconButton(
  99. onPressed: () {
  100. cityResult.province = proviceNameByIndex(provinceIndex);
  101. cityResult.provinceCode = provinceList[provinceIndex]["no"].padRight(6, '0');
  102. cityResult.city = cityList[cityIndex]["name"];
  103. cityResult.cityCode = cityList[cityIndex]["no"].padRight(6, '0');
  104. cityResult.county = countyList[countyIndex]["name"];
  105. cityResult.countyCode = countyList[countyIndex]["no"].padRight(6, '0');
  106. Navigator.pop(context, cityResult);
  107. },
  108. icon: Text(
  109. "确认",
  110. style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor),
  111. )),
  112. ],
  113. ),
  114. Divider(),
  115. _buildPickers(),
  116. ],
  117. ),
  118. ),
  119. );
  120. }
  121. Widget _buildButtons() {
  122. Widget buildButton(String text, Function onTap) {
  123. return CupertinoButton(
  124. child: Text(text),
  125. onPressed: onTap,
  126. );
  127. }
  128. return Container(
  129. color: Colors.white,
  130. height: 40.0,
  131. child: Row(
  132. children: <Widget>[
  133. buildButton("取消", () {
  134. Navigator.pop(context);
  135. }),
  136. Expanded(
  137. child: Container(),
  138. ),
  139. buildButton("确定", () {
  140. cityResult.province = proviceNameByIndex(provinceIndex);
  141. cityResult.provinceCode = provinceList[provinceIndex]["no"].padRight(6, '0');
  142. cityResult.city = cityList[cityIndex]["name"];
  143. cityResult.cityCode = cityList[cityIndex]["no"].padRight(6, '0');
  144. cityResult.county = countyList[countyIndex]["name"];
  145. cityResult.countyCode = countyList[countyIndex]["no"].padRight(6, '0');
  146. Navigator.pop(context, cityResult);
  147. }),
  148. ],
  149. ),
  150. );
  151. }
  152. Widget _buildPickers() {
  153. return Expanded(
  154. child: Row(
  155. children: <Widget>[
  156. Expanded(child: buildProvincePicker()),
  157. Expanded(child: buildCityPicker()),
  158. // Expanded(child: buildCountyPicker()),
  159. ],
  160. ),
  161. );
  162. }
  163. Widget buildProvincePicker() {
  164. return CupertinoPicker.builder(
  165. itemExtent: 40,
  166. scrollController: provinceScrollController,
  167. backgroundColor: Colors.white,
  168. onSelectedItemChanged: onProvinceChanged,
  169. itemBuilder: _buildProvinceItem,
  170. childCount: provinceList.length,
  171. );
  172. }
  173. Widget _buildProvinceItem(BuildContext context, int index) {
  174. var name = provinceList[index]["name"];
  175. return _buildTextItem(name);
  176. }
  177. Widget buildCityPicker() {
  178. _log("_build city picker");
  179. return CupertinoPicker.builder(
  180. key: ValueKey(this.cityList),
  181. itemExtent: 40,
  182. scrollController: cityScrollController,
  183. backgroundColor: Colors.white,
  184. onSelectedItemChanged: onCityChanged,
  185. itemBuilder: _buildCityItem,
  186. childCount: cityList.length,
  187. );
  188. }
  189. Widget _buildCityItem(BuildContext context, int index) {
  190. var name = cityList[index]["name"];
  191. return _buildTextItem(name);
  192. }
  193. Widget buildCountyPicker() {
  194. _log("_build county picker");
  195. return CupertinoPicker.builder(
  196. key: ValueKey(this.countyList),
  197. itemExtent: 40,
  198. scrollController: countyScrollController,
  199. backgroundColor: Colors.white,
  200. onSelectedItemChanged: onCountyChanged,
  201. itemBuilder: _buildCountyItem,
  202. childCount: countyList.length,
  203. );
  204. }
  205. Widget _buildCountyItem(BuildContext context, int index) {
  206. var name = countyList[index]["name"];
  207. _log("county $index name = $name");
  208. return _buildTextItem(name);
  209. }
  210. Widget _buildTextItem(String text) {
  211. return Container(
  212. color: Colors.white,
  213. alignment: Alignment.center,
  214. padding: const EdgeInsets.symmetric(horizontal: 5.0),
  215. child: Text(
  216. text,
  217. textAlign: TextAlign.center,
  218. style: const TextStyle(fontSize: 14.0),
  219. ),
  220. );
  221. }
  222. void onProvinceChanged(int value) {
  223. _log("onProvinceChanged value = $value");
  224. provinceIndex = value;
  225. cityIndex = 0;
  226. countyIndex = 0;
  227. cityResult.province = proviceNameByIndex(value);
  228. cityResult.city = cityList[0]["name"];
  229. cityResult.county = countyList[0]["name"];
  230. cityScrollController.jumpTo(0);
  231. // countyScrollController.jumpTo(0);
  232. cityScrollController = FixedExtentScrollController(initialItem: 0);
  233. countyScrollController = FixedExtentScrollController(initialItem: 0);
  234. setState(() {});
  235. }
  236. void onCityChanged(int value) {
  237. _log("onCityChanged value = $value");
  238. cityIndex = value;
  239. countyIndex = 0;
  240. cityResult.city = cityList[value]["name"];
  241. cityResult.county = countyList[0]["name"];
  242. countyScrollController = FixedExtentScrollController(initialItem: 0);
  243. setState(() {});
  244. }
  245. void onCountyChanged(int value) {
  246. _log("onCountyChanged value = $value");
  247. countyIndex = value;
  248. cityResult.county = countyList[value]["name"];
  249. setState(() {});
  250. }
  251. }
  252. void _log(msg) {
  253. // print(msg);
  254. }